在Using块中注入UnitOfWork

时间:2012-10-31 15:01:13

标签: asp.net-mvc design-patterns ninject repository-pattern unit-of-work

我在UnitOfWork / Repository / MVC应用程序上工作。现在这一切都很好,我想将UnitOfWork与控制器分离。一种方法是在控制器的构造函数中使用Ninject(或其他)注入依赖项。但是,这意味着UnitOfWork将与控制器同时进行实例化。

我想使用UnitOfWork的方式是使用像这样的块:

using(var unitOfWork = new IUnitOfWork)
{
    return unitOfWork.GetRepository<IEmployeesRepository>().GetAllEmployees();
}

显然你不能实例化一个接口,你的实例是一个注入依赖注入器的实现,但是如何将它注入using子句呢?

我看到了Property注入和Method注入,但我不确定如何使用它来实现我的目标。

4 个答案:

答案 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