0

将代码放在我的Global.asax.cs和两个控制器(一个基于另一个:MasterController)中我似乎没有发现我怎么能从MasterController解析我的WindsorContainer中的存储库注册...在HomeController中也是如此,并且完美地工作......我做错了什么?Castle Windsor:主控制器无法解析容器中的注册组件

的Global.asax.cs:

private IWindsorContainer _container; 

protected void Application_Start() 
{ 
    InitializeContainer(); 
    RegisterRoutes(RouteTable.Routes); 
} 

protected void Application_End() 
{ 
    this._container.Dispose(); 
} 

protected void Application_EndRequest() 
{ 
    if (_container != null) 
    { 
     var contextManager = _container.Resolve<IContextManager>(); 
     contextManager.CleanupCurrent(); 
    } 
} 

private void InitializeContainer() 
{ 
    _container = new WindsorContainer(); 

    ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container)); 

    // Register context manager. 
    _container.Register(
     Component.For<IContextManager>() 
     .ImplementedBy<EFContextManager>() 
     .LifeStyle.Singleton 
     .Parameters(
      Parameter.ForKey("connectionString").Eq(ConfigurationManager.ConnectionStrings["ProvidersConnection"].ConnectionString) 
     ) 
    ); 

     //Products repository   
    _container.Register(
     Component.For<IProductRepository>() 
     .ImplementedBy<ProductRepository>() 
     .LifeStyle.Singleton 
    ); 

    // Register all MVC controllers 
    _container.Register(AllTypes.Of<IController>() 
     .FromAssembly(Assembly.GetExecutingAssembly()) 
     .Configure(c => c.LifeStyle.Transient) 
    ); 

} 

Controller基:

public class MasterController : Controller 
{ 
    private IProductRepository _productRepository; 

    public ProductController(IProductRepository product) 
    { 
     _productRepository = product; 
    } 

    public ActionResult Index() 
    { 
     ViewData["product"] = _productRepository.FindOne(123); 
     return View(); 
    } 
} 

控制器基于MasterController:

public class ProductController : MasterController 
{ 
    private IProductRepository _productRepository; 

    public ProductController(IProductRepository product) 
    { 
     _productRepository = product; 
    } 

    public ActionResult Search(int id) 
    { 
     ViewData["product"] = _productRepository.FindOne(id);  
     return View(); 
    } 
} 

回答

1

现在按预期工作,ViewDatas可从任何控制器/视图访问。

首先我创造,我存储我的温莎容器,所以它可以从任何控制器访问的公共类:

public static class IOCcontainer 
{ 
    public static IWindsorContainer Container { get; set; } 
} 

然后在我的global.asax.cs我:

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 
    RegisterRoutes(RouteTable.Routes); 
    InitializeContainer(); 
} 

private void InitializeContainer() 
{ 
    _container = new WindsorContainer(); 

    // Register context manager. 
    _container.Register(
     Component.For<IContextManager>() 
     .ImplementedBy<EFContextManager>() 
     .LifeStyle.Singleton 
     .Parameters(
      Parameter.ForKey("connectionString").Eq(ConfigurationManager.ConnectionStrings["ProvidersConnection"].ConnectionString) 
     ) 
    ); 

     //Products repository   
    _container.Register(
     Component.For<IProductRepository>() 
     .ImplementedBy<ProductRepository>() 
     .LifeStyle.Singleton 
    ); 

    // Register all MVC controllers 
    _container.Register(AllTypes.Of<IController>() 
     .FromAssembly(Assembly.GetExecutingAssembly()) 
     .Configure(c => c.LifeStyle.Transient) 
    ); 

    IOCcontainer.Container = _container; //set the container class with all the registrations 

    ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(_container)); 
} 

所以,现在在我的主控制器我可以使用:

public class MasterController : Controller 
{ 

    private IProductRepository g_productRepository; 

    public MasterController() : this(null,null,null,null,null) 
    { 
    } 

    public MasterController(IProductRepository productRepository) 
    { 
     g_productRepository = productRepository ?? IOCcontainer.Container.Resolve<IProductRepository>(); 
    } 

    //I don't use an action here, this will make execute it for any action in any controller 
    protected override void OnActionExecuting(ActionExecutingContext context) 
    { 
     if (!(context.ActionDescriptor.ActionName.Equals("Index") && context.Controller.ToString().IndexOf("Home")>0)) { 
     //I now can use this viewdata to populate a dropdownlist along the whole application 
     ViewData["products"] = g_productRepository.GetProducts().ToList().SelectFromList(x => x.Id.ToString(), y => y.End.ToShortDateString()); 
     } 
    } 
} 

然后控制器的休息:

//will be based on MasterController 
public class AboutController : MasterController 
{ 

} 

public ActionResult Index() 
{ 
    return View(); 
} 

etc... 

可能不是最优雅的方式来做到这一点,但它会做,直到我找到更好的方式或其他人照亮我的脑海!

相关问题