通过ninject解决依赖关系" ToProvider"方法,它基于HttpContext.Current

时间:2015-11-24 13:33:16

标签: c# .net asp.net-mvc dependency-injection ninject

我有分层的asp.net MVC应用程序。我的应用程序具有以下架构:

  1. DomainLayer,包含域对象
  2. DAL(存储库模式),仅引用DomainLayer
  3. BLL,引用了DomainLayer和DAL
  4. PresentationLayer(Web),引用了DamainLayer和BLL
  5. 我有单独的图层(让我们称之为DependencyResolver),它负责通过所有应用程序层解析依赖关系。我使用Ninject依赖解析器。该项目引用了DomainLayer,DAL和BLL

    我需要根据记录的用户角色以不同的方式解决某些对象的依赖关系。例如,我有两个相同IOrderRepository的实现:OrderSQLRepository和OrderMemoryRepository:

    对于UserRole.Admin,我必须致电

    Bind<IOrderRepository>().To<OrderSQLRepository>();
    

    对于其他用户,我需要将接口绑定到IOrderMemoryRepository,它接受Session作为构造函数参数,以临时存储会话中的值。

    Bind<IOrderRepository>().To<OrderMemoryRepository>().WithConstructorArgument("pSession", HttpContext.Current.Session);
    

    因为有条件的情况,我使用ToProvider方法:

    Bind<IOrderRepository>().ToProvider<OrderRepositoryProvider>();
    
    public class OrderRepositoryProvider : IProvider
        {
            public Type Type { get { return typeof(IOrderRepository); } }
            public object Create(IContext context)
            {
                    if (HttpContext.Current.User.IsInRole("Admin"))
                    {
                        return context.Kernel.Get<OrderMemoryRepository>(new ConstructorArgument("pSession", HttpContext.Current.Session["Orders"]));
                    }
    
            return context.Kernel.Get<OrderSQLRepository>();
        }
    }
    

    但是由于绑定是在单独的项目中进行的,它没有引用System.Web.Mvc命名空间,所以我无法使用HttpContext.Current。

    那么你会建议什么,我是正确的方向还是我应该使用不同的方法,或者如果方向是正确的,我怎样才能将HttpContext.Current传递给NinjectModule的Load()方法或者传递给OrderRepositoryProvider

1 个答案:

答案 0 :(得分:1)

您走在正确的轨道上,但是,通常在Web应用程序中,Web层是组合根(包含所有绑定),因为它是应用程序的入口点。换句话说,将所有绑定作为NinjectModules放入Web层。

此外,您可以考虑为要使用的HttpContext值创建包装器。例如,IHttpContextHttpContext.Current.User实现getter,然后使用提供程序中的接口而不是具体的HttpContext.Current。我会做同样的事情来从会话中检索订单,即ISessionOrders,然后Ninject将能够在没有构造函数参数的情况下解析OrderMemoryRepository的依赖关系。

所以你会有:

public object Create(IContext context)
{
    if (context.Kernel.Get<IHttpContext>().User.IsInRole("Admin"))
    {
        return context.Kernel.Get<OrderMemoryRepository>();
    }

    return context.Kernel.Get<OrderSQLRepository>();
}