工作单元模式

时间:2011-02-09 09:09:26

标签: .net design-patterns dependency-injection unit-of-work

我正在寻找关于工作单元模式的一些建议。

工作单元上的提交是多次调用还是只调用一次,然后将对象留下来进行垃圾回收?

注入工作单元是否是一个好主意,或者在请求对象执行某些工作时是否应该在方法调用中传递它?

2 个答案:

答案 0 :(得分:5)

实现工作单元模式的类型实例通常只有一个需要控制其生命周期的所有者。像CommitOpenCloseDispose这样的方法通常是强烈的信号,应该明确控制类型(或者在适当的情况下放在抽象后面)。

由于这个原因,最好不要注入一个工作单元本身,而是注入一个知道如何创建这样一个工作单元的类型:工厂。

在这种情况下,工作单元用作上下文,当其他对象需要在同一个上下文中执行操作时(例如,保持操作原子),您需要传递它。这可能如下所示:

public class MyCommand
{
    private readonly IUnitOfWorkFactory factory;

    public MyCommand(IUnitOfWorkFactory factory)
    {
        this.factory = factory;
    }

    public void Execute()
    {
        using (var context = this.factory.CreateNew())
        {
            this.DoSomeNiceThings(context);

            context.Commit();
        }
    }
}

许多DI框架为您提供了定义对象及其依赖项运行的上下文的可能性。这允许您注入工作单元本身并在其所有依赖项中注入相同的实例。这是一个非常有用的功能,但不是我在这个特定场景中会做的事情,因为代码的正确性取决于您配置工作单元范围的方式。这使得您的代码非常隐含,难以遵循并且易于破解。 IMO这样的功能在场景中特别有用,因为消费者不关心依赖性。因此,此功能对于性能优化,实现缓存策略等非常有用。

  

是工作单位的提交   多次召唤或只召唤一次   然后离开对象   垃圾收集?

是否多次调用Commit是有效的方案取决于您的设计方式。在我的生产应用程序中,我经常在一个事务中运行我的工作单元,这允许我将操作提交到数据库(例如,获取数据库生成的密钥),同时保持业务操作的原子性。

我希望这会有所帮助。

答案 1 :(得分:0)

工作单元背后的想法是封装“工作单元”,例如在单个方法中从操作中提取的所有更改(例如,添加具有特定角色的用户,将添加用户以及与之相关的角色)用户)。

您可以使用一个工作单元来“批处理”这些更改并一次性执行它们(通常通过事务处理 - 因为不同的操作构成一个工作单元,如果一个工作失败 - 全部应该)

实际上,每个工作单元只调用一次commit。大多数ORM / s实体框架/ nhibernate允许您通过单个工作单元执行多个提交,每个工作单元与表示工作单元的特定事务相关联。