我有分层的asp.net MVC应用程序。我的应用程序具有以下架构:
我有单独的图层(让我们称之为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
答案 0 :(得分:1)
您走在正确的轨道上,但是,通常在Web应用程序中,Web层是组合根(包含所有绑定),因为它是应用程序的入口点。换句话说,将所有绑定作为NinjectModules放入Web层。
此外,您可以考虑为要使用的HttpContext值创建包装器。例如,IHttpContext
为HttpContext.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>();
}