Asp.net mvc Ninject.MVC3,是否将DependencyResolver传递给服务层?
在具有Ninject.MVC 2.2.0.3()的MVC3应用程序中,我没有将repostories直接注入控制器,而是尝试创建一个包含businesslogic的服务层,并将repostories注入其中。我将ninject DependencyResolver作为动态对象传递给服务层(因为我不想在那里引用mvc或ninject)。然后我调用它上的GetService,以获取具有我在NinjectHttpApplication模块中指定的绑定和生存期的存储库。编辑:简而言之,它失败了 在这种情况下,如何将IoC容器传递到服务层?(不同的方法也非常受欢迎。) 编辑:下面是一个示例,说明我如何理解答案和评论 我应该避免使用服务定位器,而是使用依赖注入。假设我想为Northwind的产品和类别创建一个管理站点。我根据表定义创建模型、存储库、服务、控制器和视图。此时服务直接调用存储库,没有逻辑。我有功能支柱,视图显示原始数据。这些绑定是为NinjectMVC3配置的:Asp.net mvc Ninject.MVC3,是否将DependencyResolver传递给服务层?,asp.net-mvc,asp.net-mvc-3,inversion-of-control,ninject,ninject-2,Asp.net Mvc,Asp.net Mvc 3,Inversion Of Control,Ninject,Ninject 2,在具有Ninject.MVC 2.2.0.3()的MVC3应用程序中,我没有将repostories直接注入控制器,而是尝试创建一个包含businesslogic的服务层,并将repostories注入其中。我将ninject DependencyResolver作为动态对象传递给服务层(因为我不想在那里引用mvc或ninject)。然后我调用它上的GetService,以获取具有我在NinjectHttpApplication模块中指定的绑定和生存期的存储库。编辑:简而言之,它失败了 在这种情
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<ICategoryRepository>().To<CategoryRepository>();
kernel.Bind<IProductRepository>().To<ProductRepository>();
}
产品和服务:
protected readonly IProductRepository _productRepository;
public ProductsService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
我现在不需要解耦服务,但已经准备好模拟数据库。要在“产品/编辑”中显示类别下拉列表,我创建了一个ViewModel,其中除包含产品外还包含类别:
public class ProductViewModel
{
public Product Product { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
我将GET Edit操作更改为返回视图(_productsService.GetProductViewModel(id))代码>和编辑视图以显示下拉列表:
@model Northwind.BLL.ProductViewModel
...
@Html.DropDownListFor(pvm => pvm.Product.CategoryId, Model.Categories
.Select(c => new SelectListItem{Text = c.Name, Value = c.Id.ToString(), Selected = c.Id == Model.Product.CategoryId}))
这方面的一个小问题,也是我误用服务定位器的原因,是ProductController中的其他操作方法都不需要类别存储库。我觉得这是一种浪费,除非需要,否则不符合逻辑。我遗漏了什么吗?您不需要传递对象,您可以这样做
//global.aspx
因此,在这一个我设置所有的ninject的东西。我制作了一个包含3个文件的内核来分割我所有的绑定,这样很容易找到
在我的服务层类中,您只需传入所需的接口。这个服务类位于它自己的项目文件夹中,我保存了所有的服务层类,并且没有对ninject库的引用
//服务中心
private readonly IRepo repo;
// constructor
public Service(IRepo repo)
{
this.repo = repo;
}
这就是我的ServiceModule的外观(在global.aspx中创建的内容)
//ServiceModule()
公共类ServiceModule:NinjectModule
{
公共覆盖无效负载()
{
绑定()到();
}
}
请参见如何将接口绑定到repo。现在,每次看到该接口时,它都会自动将Repo类绑定到该接口。所以你不需要把物体传来传去
您不必担心将.dll导入服务层。例如,我在自己的项目文件中有我的服务类,您在上面看到的所有内容(当然除了服务类)都在我的webui项目中(其中有my views和global.aspx)
Ninject不关心服务是否在不同的项目中,因为我猜它是在webui项目中被引用的
编辑
忘了给你NinjectDependecyResolver
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IResolutionRoot resolutionRoot;
public NinjectDependencyResolver(IResolutionRoot kernel)
{
resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
return resolutionRoot.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return resolutionRoot.GetAll(serviceType);
}
}
公共类NinjectDependencyResolver:IDependencyResolver
{
私有只读IResolutionRoot resolutionRoot;
公共NinjectDependencyResolver(IResolutionRoot内核)
{
resolutionRoot=内核;
}
公共对象GetService(类型serviceType)
{
返回resolutionRoot.TryGet(serviceType);
}
公共IEnumerable GetServices(类型serviceType)
{
返回resolutionRoot.GetAll(serviceType);
}
}
谢谢您的详细回答!因此,与其在服务中随意创建存储库,不如确保服务中的所有方法都使用相同的存储库,或者不要担心创建不需要的存储库?请不要使用自定义DependencyResolver和应用程序。\u从此答案开始。继续使用Ninject.MVC3!只需实现如上所述的构造函数注入。如上所述,不需要将Ninject用作服务定位器。@Remo-Gloor-为什么不使用DependencyResolver。我的意思是,它们内置在MVC3.0中,为什么要使用独立插件?更多关于为什么在上面使用Ninject.MVC3的信息。我一直在寻找最好的方法。但我想知道为什么一种方法比另一种更好。@Grastveit-我不确定我是否完全理解你的意思,但通常我会使用多个存储库。我尝试为每个db表创建一个存储库,但您可以根据需要对常见的存储库进行分组。因此,如果说我有一个ProductService层,我可能会有一个ProductRepo,但我也可能有一个AccountRepo,因为我可能需要获取用户信息。因此,只需向构造函数服务(IRepo、IAccountRepo、IPProductrepo)@Remo Gloor添加另一个绑定,然后向构造函数服务(IRepo、IAccountRepo、IPProductrepo)添加另一个参数-我可能会开始一个新的问题,即为什么要使用DependencyResolver或Ninject.MVC3,但今晚不会了。我会做tmr并在这个帖子中发布链接,因为这可能对Aasmund也有好处。我没有意识到我描述了服务定位器。
protected void Application_Start()
{
// Hook our DI stuff when application starts
SetupDependencyInjection();
}
public void SetupDependencyInjection()
{
// Tell ASP.NET MVC 3 to use our Ninject DI Container
DependencyResolver.SetResolver(new NinjectDependencyResolver(CreateKernel()));
}
protected IKernel CreateKernel()
{
var modules = new INinjectModule[]
{
new NhibernateModule(),
new ServiceModule(),
new RepoModule()
};
return new StandardKernel(modules);
}
private readonly IRepo repo;
// constructor
public Service(IRepo repo)
{
this.repo = repo;
}
// ServiceModule()
public class ServiceModule : NinjectModule
{
public override void Load()
{
Bind<IRepo>().To<Repo>();
}
}
public class NinjectDependencyResolver : IDependencyResolver
{
private readonly IResolutionRoot resolutionRoot;
public NinjectDependencyResolver(IResolutionRoot kernel)
{
resolutionRoot = kernel;
}
public object GetService(Type serviceType)
{
return resolutionRoot.TryGet(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return resolutionRoot.GetAll(serviceType);
}
}