首页 > 解决方案 > 为什么 Unity (DI) 可以在 Controller 中工作,而不能在我的服务层中工作?

问题描述

我过去使用过很多不同DI的容器,但从未使用过 Unity(特别是Unity 4.0.1)。

我正在使用.NET MVC具有典型 3 层架构的普通旧应用程序。Repository -> Domain -> WebUI.

我需要知道我做错了什么,这样我才能让我注册的依赖项在域层上工作。这是我的global.asax.

protected void Application_Start()
{
    // ...

    IUnityContainer container = new UnityContainer();
    RegisterDependencies(container);
    DependencyResolver.SetResolver(new WebApplicationDependencyResolver(container));
}

protected void RegisterDependencies(IUnityContainer container)
{
    container.RegisterType<IUnitOfWork, UnitOfWork>();
}

这是WebApplicationDependencyResolver上面使用的:

namespace WebApplication1.Infrastructure
{
    public class WebApplicationDependencyResolver : IDependencyResolver
    {
        private IUnityContainer _container;
        public WebApplicationDependencyResolver(IUnityContainer container)
        {
            _container = container;
        }

        public object GetService(Type serviceType)
        {
            try
            {
                return _container.Resolve(serviceType);
            }
            catch (Exception)
            {
                return null;
            }
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            try
            {
                return _container.ResolveAll(serviceType);
            }
            catch (Exception)
            {
                return null;
            }
        }
    }
}

我的Domain Layer课程CustomerService.cs(我在它自己的项目和主项目的文件夹中都使用过):

namespace WebApplication1.Services
{
    public class CustomerService
    {
        private readonly IUnitOfWork _uow;

        public CustomerService(IUnitOfWork uow)
        {
            _uow = uow;
        }
    }
}

现在,当我尝试CustomerService像这样调用控制器中的类时,它不起作用:

public ActionResult Index()
{
    var service = new CustomerService();
    return View();
}

但是如果我在控制器本身上使用解析器,它可以工作:

public class HomeController : Controller
{
    private IUnitOfWork _unitOfWork;

    public HomeController(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    public ActionResult Index()
    {
        var service = new CustomerService(_unitOfWork);
        return View();
    }
}

任何人都可以指导我正确的方向,开始DI在域层上工作吗?

标签: c#.netinversion-of-controlunity-container

解决方案


尝试在控制器中注入服务而不是注入IUnitOfWork. 然后在控制器方法中使用服务实例:

public HomeController(CustomerService service)
{
  _service = service
}

public ActionResult Index()
{
  var model = _service.GetAllCustomers();
  return View(model);
}

这应该可行,但是让您的班级依赖于另一个班级并不是一个好主意。依赖项应该是一个契约(接口)。您应该重构CustomerService以提取接口ICustomerService并将其注入控制器中。然后你需要在方法中将它注册到容器中RegisterDependencies

container.RegisterType<ICustomerService, CustomerService>();

推荐阅读