0

Avoir le code ci-dessous dans mon Global.asax.cs et deux contrôleur (l'un basé sur l'autre: MasterController) Je ne trouve pas comment puis-je résoudre le registre de dépôt dans mon WindsorContainer à partir du MasterController ... la même chose s'applique dans le HomeController et fonctionne parfaitement ... qu'est-ce que je fais mal?Castle Windsor: contrôleur principal ne résolvant pas les composants enregistrés dans le conteneur

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

} 

carte contrôleur:

public class MasterController : Controller 
{ 
    private IProductRepository _productRepository; 

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

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

contrôleur basé sur 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(); 
    } 
} 

Répondre

1

Il fonctionne comme prévu maintenant et les ViewDatas sont accessibles depuis n'importe quel contrôleur/vue.

D'abord, je crée une classe publique où je stocke mon conteneur Windsor il est accessible à partir d'un contrôleur:

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

Puis dans mes Global.asax.cs je:

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

Alors maintenant, dans mon contrôleur maître que je peux utiliser:

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

Puis le reste des contrôleurs:Probablement pas le moyen le plus élégant de le faire mais il le fera jusqu'à ce que je trouve un meilleur moyen ou quelqu'un d'autre égayer mon esprit!

Questions connexes