【问题标题】:ASP.NET MVC Castle Windsor and dependency injectionASP.NET MVC Castle Windsor 和依赖注入
【发布时间】:2013-08-30 20:52:17
【问题描述】:

我正在尝试使用 Castle Windsor 和依赖注入创建一个 ASP.NET MVC 项目。一切正常,期待以下内容:

全球.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());

家庭控制器

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 属性为空,因为容器无法解析 CustomMessage 构造函数中的 IController 依赖项。但我不知道如何解决这个问题。

Castle 容器中的内部错误消息显示如下:

此组件的某些依赖项无法静态解析。 'User.Web.UI.Helper.Messages.CustomMessage' 正在等待以下依赖项: - 未注册的服务“System.Web.Mvc.IController”。

我在网上看了很多,但我找不到任何有用的提示或解决我的问题的方法。

【问题讨论】:

  • 我不知道这是否有助于找到解决方案,所以我没有将其标记为答案。当内核通过构造函数参数注册 IAddMessage 的 CustomMessage 实现时,内核将尝试解析 IController。可能 IController 超出范围或需要先注册。

标签: asp.net-mvc dependency-injection castle-windsor


【解决方案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)

【讨论】:

    【解决方案2】:

    在 Kenneth 的帮助下,我找到了如下所示的解决方案:

    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");
     }
    

    我已经扩展了“DefaultControllerFactory”,并且我正在使用 HttpContext 将当前使用的控制器存储在当前 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>());
    ...
    

    现在效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-10
      • 2023-03-23
      • 1970-01-01
      • 2015-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多