Единица рабочего шаблона

Я ищу несколько советов о единице работы.

Коммит для единицы работы вызывается несколько раз или только один раз, а затем оставляет объект для сборки мусора?

Является ли хорошей идеей вводить единицу рабочей игры или я должен передать ее в вызове метода, когда запрашиваю объекты для выполнения какой-либо работы?


person Karsten    schedule 09.02.2011    source источник


Ответы (2)


Экземпляры типов, которые реализуют шаблон единицы работы, обычно имеют одного владельца, которому необходимо контролировать его время существования. Такие методы, как Commit, Open, Close и Dispose, часто являются сильными сигналами того, что тип должен управляться явно (или, если это уместно, размещаться за абстракцией).

По этой причине лучше не внедрять сам экземпляр единицы работы, а внедрять тип, который знает, как создать такую ​​единицу работы: фабрику.

Единица работы в этом случае функционирует как контекст, и когда другим объектам необходимо выполнять операции в том же контексте (например, чтобы сохранить операцию атомарной), вам необходимо передать ее. Это может выглядеть так:

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 допустимым сценарием, зависит от того, как вы его спроектируете. В моих производственных приложениях я часто запускаю свою единицу работы внутри транзакции, что позволяет мне фиксировать операции в базе данных (например, для получения сгенерированных базой данных ключей), сохраняя при этом атомарность бизнес-операции.

Надеюсь, это поможет.

person Steven    schedule 09.02.2011
comment
Я написал сообщение в блоге о написании, подделке и внедрении единиц работы (с использованием LINQ в качестве уровня абстракции) в ваше приложение. Это может вас заинтересовать: bit.ly/gHLubu. - person Steven; 10.02.2011

Идея единицы работы заключается в инкапсуляции «единицы работы», такой как все изменения, требуемые от действий в рамках одного метода (например, добавить пользователя с определенными ролями, пользователь будет добавлен и роли, связанные с пользователем) .

Вы бы использовали единицу работы, чтобы «сгруппировать» эти изменения и выполнить их за один раз (обычно через транзакцию, потому что разные действия составляют одну единицу работы, если одно терпит неудачу — все должны)

Так что на самом деле вы бы вызывали коммит только один раз на единицу работы. Большинство ORM/s, таких как entity framework/nhibernate, позволяют вам выполнять несколько коммитов через одну единицу работы, каждая из которых связана с определенной транзакцией, представляющей единицу работы.

person Shelakel    schedule 06.07.2012