加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – Ninject.MVC3,将DependencyResolver传递给服务层

发布时间:2020-12-15 19:01:02 所属栏目:asp.Net 来源:网络整理
导读:在使用Ninject.MVC 2.2.0.3( after merge)的MVC3应用程序中,我不是直接将控制器注册到控制器中,而是试图创建一个包含商业用途的服务层,并在那里注入该重定向库.我将ninject-DependencyResolver作为一个动态对象传递给服务层(因为我不想引用mvc和ninject).然
在使用Ninject.MVC 2.2.0.3( after merge)的MVC3应用程序中,我不是直接将控制器注册到控制器中,而是试图创建一个包含商业用途的服务层,并在那里注入该重定向库.我将ninject-DependencyResolver作为一个动态对象传递给服务层(因为我不想引用mvc和ninject).然后我调用GetService来获取我在NinjectHttpApplicationModule中指定的绑定和生命周期的存储库.编辑:简而言之,它失败了.

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

编辑:这是一个例子来说明我如何理解答案和意见.

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

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

存储库实例由ninject通过两层构造函数注入在ProductController中创建:

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

和产品服务:

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

ProductsService现在需要一个CategoriesRepository来创建它.

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编辑操作以返回View(_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中的其他操作方法都不需要category-repository.我觉得创建它是一种浪费,不合逻辑,除非需要.我错过了什么吗?

解决方法

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

// 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个文件做一个内核来分割我的所有绑定,所以很容易找到.

在我的服务层类中,您只需传递所需的界面.这个服务类在它自己的项目文件夹中,我保留所有的服务层类,并没有引用ninject库.

// service.cs

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

这是我的ServiceModule的外观(在global.aspx中创建的)

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

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


        }

    }

看到我如何将界面绑定到repo.现在每次看到该界面时,它会自动将Repo类绑定到它.所以你不需要传递对象或任何东西.

您不必担心将.dll导入服务层.例如,我的服务类在自己的项目文件和上面看到的所有内容(期望服务类当然)在我的webui项目(我的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);
        }
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读