Ninject.MVC3,通DependencyResolver到服务层? [英] Ninject.MVC3, Pass DependencyResolver to service-layer?

查看:211
本文介绍了Ninject.MVC3,通DependencyResolver到服务层?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在与Ninject.MVC 2.2.0.3(<一个一个MVC3应用href=\"http://www.planetgeek.ch/2011/02/22/ninject-mvc3-and-ninject-web-mvc3-merged-to-one-package/\">after合并),而不是直接注射到repostories控制器我试图让包含businesslogic和注入repostories有一个服务层。我通过ninject-DependencyResolver到服务层作为一个动态对象(因为我不想引用MVC也ninject那里)。然后,我调用它的GetService得到与我在NinjectHttpApplicationModule指定绑定和寿命库。编辑:简而言之,它失败。

In a MVC3-application with Ninject.MVC 2.2.0.3 (after merge), instead of injecting repostories directly into controllers I'm trying to make a service-layer that contain the businesslogic and inject the repostories there. I pass the ninject-DependencyResolver to the service-layer as a dynamic object (since I don't want to reference mvc nor ninject there). Then I call GetService on it to get repositories with the bindings and lifetimes I specify in NinjectHttpApplicationModule. In short, it failed.

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

How can the IoC-container be passed to the service-layer in this case? (Different approaches are also very welcome.)

修改:这是为了说明我所理解的答案和注释的例子

EDIT: Here is an example to illustrate how I understand the answer and comments.

我应该避免的服务定位器(防)模式,而使用依赖注入。因此,可以说,我想创建一个管理员,网站产品和品类罗斯文。我根据表定义创建模型,仓库,服务,控制器和视图。该服务在这一点上直接打电话到仓库,没有逻辑。我有功能柱子和视图显示原始数据。这些绑定配置为NinjectMVC3:

I should avoid the service locator (anti-)pattern and instead use dependency injection. So lets say I want to create an admin-site for Products and Categories in Northwind. I create models, repositories, services, controllers and views according to the table-definitions. The services call directly to the repositories at this point, no logic there. I have pillars of functionality and the views show raw data. These bindings are configured for NinjectMVC3:

    private static void RegisterServices(IKernel kernel)
    {
        kernel.Bind<ICategoryRepository>().To<CategoryRepository>();
        kernel.Bind<IProductRepository>().To<ProductRepository>();
    }       

库-实例由ninject通过构造函数注入两层创建的,在ProductController的:

Repository-instances are created by ninject via two layers of constructor injection, in the ProductController:

private readonly ProductsService _productsService;
public ProductController(ProductsService productsService)
{
    // Trimmed for this post: nullchecks with throw ArgumentNullException 
    _productsService = productsService;
}

和ProductsService:

and ProductsService:

protected readonly IProductRepository _productRepository;
public ProductsService(IProductRepository productRepository)
{
    _productRepository = productRepository;
}

我有没有必要去耦的服务,但现在有ppared为嘲讽分贝$ P $。结果
要显示产品类别的下拉列表/编辑我做持有的类别,除了产品一个ViewModel:

I have no need to decouple the services for now but have prepared for mocking the db.
To show a dropdown of categories in Product/Edit I make a ViewModel that holds the categories in addition to the Product:

public class ProductViewModel
{
    public Product Product { get; set; }
    public IEnumerable<Category> Categories { get; set; }
}

该ProductsService现在需要一个CategoriesRepository创建它。

The ProductsService now needs a CategoriesRepository to create it.

    private readonly ICategoryRepository _categoryRepository;

    // Changed constructor to take the additional repository
    public ProductsServiceEx(IProductRepository productRepository, 
        ICategoryRepository categoryRepository)
    {
        _productRepository = productRepository;
        _categoryRepository = categoryRepository;
    }

    public ProductViewModel GetProductViewModel(int id)
    {
        return new ProductViewModel
                   {
                       Product = _productRepository.GetById(id),
                       Categories = _categoryRepository.GetAll().ToArray(),
                   };
    }

我改变GET编辑-行动返回查看(_productsService.GetProductViewModel(ID)); 和编辑视图显示一个下拉:

I change the GET Edit-action to return View(_productsService.GetProductViewModel(id)); and the Edit-view to show a dropdown:

@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的其他行动的方法需要的类别的存储库。我觉得这是一种浪费,不符合逻辑,除非需要创建它。我缺少的东西吗?

One small problem with this, and the reason I went astray with Service Locator, is that none of the other action-methods in ProductController need the categories-repository. I feel it's a waste and not logical to create it unless needed. Am I missing something?

推荐答案

您不需要传递对象周围,你可以做这样的事情。

You don't need to pass the object around you can do something like this

// global.aspx

// global.aspx

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

所以在这一块我安装所有的东西ninject。我做一个籽粒与3档拆了我所有的约束力,所以很容易找到。

So in this one I setup all the ninject stuff. I make a kernal with 3 files to split up all my binding so it is easy to find.



在我的服务层类,你只是通过你想要的接口。这个服务类是在我把我所有的服务层类,并没有提及ninject库它自己的项目文件夹。


In my service layer class you just pass in the interfaces you want. This service class is in it's own project folder where I keep all my service layer classes and has no reference to the ninject library.

// service.cs

// service.cs

    private readonly IRepo repo;
    // constructor
        public Service(IRepo repo)
        {
            this.repo = repo;
        }


这是我的ServiceModule的样子(什么是在global.aspx创建)


This is how my ServiceModule looks like(what is created in the global.aspx)

// ServiceModule()
 public class ServiceModule : NinjectModule
    {
        public override void Load()
        {

           Bind<IRepo>().To<Repo>();


        }

    }       

SEEE我怎么绑定接口回购。现在每次看到它的界面它将回购类自动绑定到它。所以,你不需要通过围绕对象或任何东西。

Seee how I bind the interface to the repo. Now every time it see that interface it will automatically bind the the Repo class to it. So you don't need to pass the object around or anything.

您不需要有关导入.dll文件到您的服务层的担心。比如我有我的服务类在他们自己的项目文件,你在上面看到的一切(预计服务类课程)是在我的WebUI中的项目(在我的意见,并global.aspx是)。

You don't need worry about importing .dll into your service layer. For instance I have my service classes in their own project file and everything you see above(expect the service class of course) is in my webui project(where my views and global.aspx is).

Ninject不关心,如果该服务是在不同的项目中,因为我想这是在WebUI项目中被引用。

Ninject does not care if the service is in a different project since I guess it is being referenced in the webui project.

修改

忘了给你的NinjectDependecyResolver

Forgot to give you the 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);
        }
    }

这篇关于Ninject.MVC3,通DependencyResolver到服务层?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆