0

在我的 Global.asax.cs 和两个控制器(一个基于另一个:MasterController)中有下面的代码我似乎没有找到如何从 MasterController 解析我的 WindsorContainer 中的存储库寄存器......同样适用在 HomeController 中并且完美运行......我做错了什么?

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

}

控制器底座:

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

1 回答 1

1

它现在按预期工作,并且可以从任何控制器/视图访问 ViewData。

首先,我创建了一个公共类来存储我的 Windsor 容器,以便可以从任何控制器访问它:

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...

可能不是最优雅的方法,但在我找到更好的方法或其他人让我头脑清醒之前,它会一直有效!

于 2010-09-23T16:30:44.620 回答