Asp.net mvc Ninject.MVC3,是否将DependencyResolver传递给服务层?

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模块中指定的绑定和生存期的存储库。编辑:简而言之,它失败了 在这种情

在具有Ninject.MVC 2.2.0.3()的MVC3应用程序中,我没有将repostories直接注入控制器,而是尝试创建一个包含businesslogic的服务层,并将repostories注入其中。我将ninject DependencyResolver作为动态对象传递给服务层(因为我不想在那里引用mvc或ninject)。然后我调用它上的GetService,以获取具有我在NinjectHttpApplication模块中指定的绑定和生存期的存储库。编辑:简而言之,它失败了

在这种情况下,如何将IoC容器传递到服务层?(不同的方法也非常受欢迎。)

编辑:下面是一个示例,说明我如何理解答案和评论

我应该避免使用服务定位器,而是使用依赖注入。假设我想为Northwind的产品和类别创建一个管理站点。我根据表定义创建模型、存储库、服务、控制器和视图。此时服务直接调用存储库,没有逻辑。我有功能支柱,视图显示原始数据。这些绑定是为NinjectMVC3配置的:

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