为什么 Unity(DI)在 Controller 工作,但在我的服务层不工作?
Why does Unity (DI) work in the Controller, but not in my service layer?
我过去使用过很多不同的 DI
容器,但从未使用过 Unity(特别是 Unity 4.0.1
)。
我正在使用具有典型 3 层架构的普通旧 .NET MVC
应用程序。 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
class CustomerService.cs
(我在它自己的项目和主项目的文件夹中都使用了):
namespace WebApplication1.Services
{
public class CustomerService
{
private readonly IUnitOfWork _uow;
public CustomerService(IUnitOfWork uow)
{
_uow = uow;
}
}
}
现在,当我尝试在我的控制器中调用 CustomerService
class 时,它不起作用:
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
在域层上工作吗?
尝试在控制器中注入服务而不是注入 IUnitOfWork
。然后在控制器方法中使用服务实例:
public HomeController(CustomerService service)
{
_service = service
}
public ActionResult Index()
{
var model = _service.GetAllCustomers();
return View(model);
}
这应该可行,但让您的 class 依赖于另一个 class 并不是一个好主意。 一个依赖应该是一个契约(接口)。您应该重构 CustomerService
以提取接口 ICustomerService
并将该接口注入控制器。然后你需要在方法 RegisterDependencies
:
中将它注册到容器中
container.RegisterType<ICustomerService, CustomerService>();
我过去使用过很多不同的 DI
容器,但从未使用过 Unity(特别是 Unity 4.0.1
)。
我正在使用具有典型 3 层架构的普通旧 .NET MVC
应用程序。 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
class CustomerService.cs
(我在它自己的项目和主项目的文件夹中都使用了):
namespace WebApplication1.Services
{
public class CustomerService
{
private readonly IUnitOfWork _uow;
public CustomerService(IUnitOfWork uow)
{
_uow = uow;
}
}
}
现在,当我尝试在我的控制器中调用 CustomerService
class 时,它不起作用:
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
在域层上工作吗?
尝试在控制器中注入服务而不是注入 IUnitOfWork
。然后在控制器方法中使用服务实例:
public HomeController(CustomerService service)
{
_service = service
}
public ActionResult Index()
{
var model = _service.GetAllCustomers();
return View(model);
}
这应该可行,但让您的 class 依赖于另一个 class 并不是一个好主意。 一个依赖应该是一个契约(接口)。您应该重构 CustomerService
以提取接口 ICustomerService
并将该接口注入控制器。然后你需要在方法 RegisterDependencies
:
container.RegisterType<ICustomerService, CustomerService>();