我在UnitOfWork / Repository / MVC应用程序上工作。现在这一切都很好,我想将UnitOfWork与控制器分离。一种方法是在控制器的构造函数中使用Ninject(或其他)注入依赖项。但是,这意味着UnitOfWork将与控制器同时进行实例化。
我想使用UnitOfWork的方式是使用像这样的块:
using(var unitOfWork = new IUnitOfWork)
{
return unitOfWork.GetRepository<IEmployeesRepository>().GetAllEmployees();
}
显然你不能实例化一个接口,你的实例是一个注入依赖注入器的实现,但是如何将它注入using子句呢?
我看到了Property注入和Method注入,但我不确定如何使用它来实现我的目标。
答案 0 :(得分:2)
使用您在容器中注册的工厂:
public class UserController : Controller
{
IUnitOfWorkFactory _factory;
public UserController(IUnitOfWorkFactory factory)
{
_factory = factory;
}
public ActionResult DoSomething()
{
using(var unitOfWork = _factory.Create())
{
return unitOfWork.GetRepository<IEmployeesRepository>().GetAllEmployees();
}
}
}
imho最好抽象出UoW处理:http://blog.gauffin.org/2012/06/how-to-handle-transactions-in-asp-net-mvc3/
答案 1 :(得分:1)
您可以通过Autofac轻松完成此操作。我确定其他IoC容器应具有相同的功能。
这是wiki的链接。
代码示例:
public class UserController : Controller
{
Func<Owned<IUnitOfWork>> unitOfWorkFactory;
public UserController(Func<Owned<IUnitOfWork>> unitOfWorkFactory)
{
this.unitOfWorkFactory = unitOfWorkFactory;
}
public ActionResult DoSomething()
{
using(var unitOfWork = this.unitOfWorkFactory().Value)
{
return unitOfWork.GetRepository<IEmployeesRepository>().GetAllEmployees();
}
}
}
无需额外注册,只需注册接口的实现。
答案 2 :(得分:0)
您不必在using块中实例化变量,您可以使用现有变量。所以,您可以像这样使用方法注入:
public ActionResult Index(IUnitOfWork unit)
{
using(unit)
{
// Do some work....
}
// Return an action
}
请理解,单位将在离开使用区块后处理,因此不应使用。
答案 3 :(得分:0)
[..]如何在using子句中注入它?
将不再有using
条款。如果IoC容器注入依赖项,则它负责它的生命周期。
您处置依赖关系并不是一个好习惯(using
完全相同)。
我看到了Property injection和Method injection
尽可能使用构造函数注入。属性/方法注入在少数特殊情况下使用它们。
构造函数注入的好处是,类可以立即清楚它的依赖项是什么。此外,只有在提供所有需要的依赖项后才能创建实例。
使用Property Injection,您可能忘记设置所需的依赖项。仅在依赖项是可选的情况下使用它,或者它具有默认实现,或者用于破坏循环依赖关系图。
使用方法注入可能会一次又一次地使用相同的方法参数使代码膨胀。
[...]如果我想在该控制器的同一个实例中使用UnitOfWork两次会发生什么。 Ninject会再次注射吗?
Ninject将两次注入相同的实例,或者将创建两个不同的实例,具体取决于您如何指示它的行为。
IoC容器允许您为注入的组件指定/配置生命周期样式。对于Ninject,请参阅how to specify Object Scopes。