2013-08-30 60 views
0

我想創建一個ASP.NET城堡溫莎和依賴注入ASP.NET MVC項目。一切工作正常遇到下列情況:ASP.NET MVC城堡溫莎和依賴注入

的Global.asax

Container = new WindsorContainer(); 
Container.Install(new WebInstaller(), new LoggingInstaller()); 

var customControllerFactory = new CustomControllerFactory(Container); 
ControllerBuilder.Current.SetControllerFactory(customControllerFactory); 

Webinstaller註冊Castle類:

string connectionStr = GetConnectionString("MainModel"); 
container.Register(Component.For(typeof(MainModelContainer)).DependsOn(new { 
      connectionString = connectionStr }).LifestylePerWebRequest()); 
container.Register(Classes.FromAssemblyContaining<MemberQueries>().InNamespace("User.EF.Queries").WithService.DefaultInterfaces().LifestylePerWebRequest()); 
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest()); 

//PROBLEM that doesn't work 
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IAddMessage>().LifestylePerWebRequest()); 

的HomeController

public IAddMessage AddMessage { get; set; } 
private readonly IMemberQueries _memberContract; 

public HomeController(IMemberQueries memberContract) 
{ 
    _memberContract = memberContract; 
} 

public ActionResult Index() 
{ 
    //PROBLEM AddMessage is Null and is not resolved automaticaly 
    AddMessage.Add("Test", MessageTypes.message); 
    return View("Index"); 
} 

IAddMessage實施

public class CustomMessage : IAddMessage 
{ 
    private IController Controller { get; set; } 

    public CustomMessage(IController controller) 
    { 
     Controller = controller; 
    } 

    public void Add(string text, MessageTypes messageTypes) 
    { 
     //TODO 
    } 
} 

IAddMessage接口

public interface IAddMessage 
{ 
    void Add(string text, MessageTypes messageTypes); 
} 

的問題是,該IAddMessage屬性爲null,因爲容器不能解析在CUSTOMMESSAGE構造函數中的一個IController依賴。但我不知道如何解決這個問題。

在城堡容器中的內部錯誤消息顯示這一點:

此組件的某些依賴性不能被靜態解決。 'User.Web.UI.Helper.Messages.CustomMessage'正在等待下列依賴項: - 未註冊的服務'System.Web.Mvc.IController'。

我在網上看了很多,但我找不到任何工作提示或解決方案,我的問題。

+0

我不知道這是否有助於找到解決方案,因此我不打算回答。當它通過構造函數參數註冊IAddMessage的CustomMessage實現時,內核將嘗試解析IController。也許IController超出範圍或需要先註冊。 –

回答

1

問題是您尚未註冊IController相關性。我想,你以爲你這樣做有以下行:

container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest()); 

這看起來像你這樣做,但你實際上做的是註冊實現這個接口的所有類。因此,當您詢問容器的HomeController時,它會知道如何解決該問題,但是,如果您要求它使用IController,則不知道是否創建HomeController或其他任何控制器。

你可能想要的是當前的主動控制器。爲此,您可能必須從CustomControllerFactory繼承並將創建的控制器保存在請求範圍中。然後,您可以從CustomMessage類中的請求範圍中檢索它。

您可以查看以下線程來看看如何做到這一點:Asp.net mvc 3- get the current controller instance (not just name)

0

與肯尼斯幫助我發現它看起來像解決方案:

private const string CurrentControllerIndexName = "CurrentControllerItem"; 

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) 
{ 
    if (controllerType == null) 
    { 
     throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path)); 
     } 

     var controller = (IController)this._container.Resolve(controllerType); 
     //I am Using the Context not the current Session! 
     if(HttpContext.Current.Items.Contains(CurrentControllerIndexName)) 
     { 
      HttpContext.Current.Items.Remove(CurrentControllerIndexName); 
     } 

     HttpContext.Current.Items.Add(CurrentControllerIndexName, controller); 

     return controller; 
    } 

public static IController GetCurrentController() 
{ 
    if(HttpContext.Current.Items.Contains(CurrentControllerIndexName)) 
    { 
     return (IController) HttpContext.Current.Items[CurrentControllerIndexName]; 
    } 

    throw new Exception("No Controller found in the Current HttpContext"); 
} 

我已經extendet了「 DefaultControllerFactory「,我正在使用HttpContext將當前的Used Controller存儲在當前的HttpRequest中,現在工作正常。

的CUSTOMMESSAGE現在看起來像:

public class CustomMessage : IAddMessage 
{ 
    public CustomMessage() 
    { 
    } 

    public void Add(string text, MessageTypes messageTypes) 
    { 
     Controller controller = (Controller)CustomControllerFactory.GetCurrentController(); 
     //TODO 
    } 
} 

和我的城堡註冊

... 
container.Register(Classes.FromAssemblyContaining<HomeController>().BasedOn<IController>().LifestylePerWebRequest()); 
container.Register(Component.For<IAddMessage>().ImplementedBy<CustomMessage>()); 
... 

那現在工作得很好。