0

以下のコードを Global.asax.cs と 2 つのコントローラー (もう 1 つは MasterController に基づいています) に持っていますが、MasterController から WindsorContainer のリポジトリ レジスタを解決する方法が見つからないようです... 同じことが当てはまります。 HomeController で完全に動作します...何が間違っていますか?

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

}

コントローラーベース:

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 に答える