Единица работы схемы - где использовать? - PullRequest
2 голосов
/ 13 января 2012

Я использую ASP.NET MVC 3 и использую шаблоны репозитория и единицы работы с NHibernate и Ninject. Я посмотрел на пару примеров ( 1 , 2 ), чтобы помочь реализовать UoW, и я просто не уверен, где Я должен использовать единицу работы , Должен ли он быть введен в мои контроллеры и вручную вызывать Commit и Rollback в моих действиях?

Вот несколько примеров кода:

Единица работы (интерфейс расширяет IDisposable и имеет Session, Commit и Rollback)

public class UnitOfWork : IUnitOfWork
{
    private readonly ISessionFactory _sessionFactory;
    private readonly ITransaction _transaction;

    public UnitOfWork(ISessionFactory sessionFactory)
    {
        _sessionFactory = sessionFactory;
        Session = _sessionFactory.OpenSession();
        Session.FlushMode = FlushMode.Auto;
        _transaction = Session.BeginTransaction(IsolationLevel.ReadCommitted);
    }

    public ISession Session { get; private set; }

    public void Commit()
    {
        if (!_transaction.IsActive)
        {
            throw new InvalidOperationException("No active transation");
        }

        _transaction.Commit();
    }

    public void Rollback()
    {
        if (_transaction.IsActive)
        {
            _transaction.Rollback();
        }
    }

    public void Dispose()
    {
        if (Session.IsOpen)
            Session.Close();
    }
}

Часть моего модуля Ninject:

Bind<IXXXRepository>().To<XXXRepository>().InRequestScope();
Bind<IYYYRepository>().To<YYYRepository>().InRequestScope();
...

Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
Bind<ISessionFactory>().ToMethod(x => NHibernateHelper.CreateConfiguration(Path.Combine(
            HostingEnvironment.ApplicationPhysicalPath,
            "bin",
            "hibernate.cfg.xml")).BuildSessionFactory()).InSingletonScope();

Bind<ISession>().ToMethod(x => x.Kernel.Get<IUnitOfWork>().Session).InRequestScope();

Все мои репозитории наследуются от класса, которому вводится ISession, и, как я уже говорил ранее в этом посте, я внедряю IUnitOfWork в мои контроллеры и при необходимости вызываю Commit и Rollback. Я делаю это правильно? Должен ли я вызывать Commit только тогда, когда я делаю обновления или удаления, и вообще не беспокоиться о том, чтобы вызывать его для выбора? Будет ли это оставлять зависшую транзакцию в конце каждого запроса?

1 Ответ

1 голос
/ 13 января 2012

Мне нравится использовать ActionFilter для автоматического запуска / фиксации единицы работы вокруг каждого запроса. Это прекрасно работает для 95% моих действий. Для немногих более сложных я добавлю UoW и управляю им явно из контроллера или службы.

Обычно я просто внедряю ISession в UnitOfWork, а также в репозитории. На самом деле нет никаких причин, по которым хранилище должно знать о единице работы, оно вообще не должно касаться транзакции.

...