Передача данных контекста из единицы работы в репозитории - PullRequest
3 голосов
/ 23 октября 2011

Я уже некоторое время использую репозитории для доступа к данным, но никогда не реализовывал ничего похожего на шаблон «Единица работы».Я начал новый проект для самообразования с использованием RavenDB и ASP.NET MVC (теоретически детали должны быть тривиальными), и я ищу, чтобы найти хороший способ обернуть бизнес-транзакции ( не веб-запросы)) в их собственных единицах работы, но у меня возникли некоторые трудности при этом.

Следующий фрагмент кода - это то, что я хотел бы увидеть:

public class UserService : IUserService
    {
        private readonly IRepository<User> _userRepository;
        private readonly IRepository<Role> _roleRepository;

        public UserService(
               IRepository<User> userRepository, 
               IRepository<Role> roleRepository)
        {
            _userRepository = userRepository;
            _roleRepository = roleRepository;
        }

        public void Register(User user)
        {
            using (var session = UnitOfWork.Begin())
            {
                _userRepository.Create(user);
                _roleRepository.AddToRole(user, Role.Public);
                session.Commit();
            }
        }
    }

Мой первый удар по интерфейсу единицы работы выглядит примерно так:

 public interface IUnitOfWork : IDisposable
    {
        void Commit();
    }

    public class UnitOfWork : IUnitOfWork
    {
        private readonly IDocumentSession _session;

        public UnitOfWork(IDocumentStore documentStore)
        {
            _session = documentStore.OpenSession("http://from:config");
        }

        public void Commit()
        {
            _session.SaveChanges();
        }

        public static IUnitOfWork Begin()
        {
            return IoC.GetInstance<IUnitOfWork>();
        }

        public void Dispose()
        {
            _session.Dispose();
        }
  }

Где я застрял - это доступ репозиториев к сеансу базы данных.Как я уже упоминал, я хотел бы обернуть бизнес-транзакции в свои собственные единицы;Я также не заинтересован в передаче сеанса / контекста в каждый метод, и большинство других решений, которые я видел, используют статические методы и / или хранилище в чем-то вроде веб-сеанса.Все это делает меня немного неудобным;есть ли что-то ключевое, чего мне не хватает во всей этой концепции Единицы Работы?

Ответы [ 2 ]

1 голос
/ 05 ноября 2011

Мне не нравится концепция TransactionScope, и дальнейшие исследования и дискуссии привели меня к мысли, что то, что я пытаюсь сделать, просто неосуществимо.

В конце концов, хранилища внутриконтекст UnitOfWork должен (явно) знать о UnitOfWork.Я еще не определился, по какому пути идти, но я собираюсь сделать что-то вроде одного из следующих:

using (var session = UnitOfWork.Begin())
            {
                _userRepository.Use(session).Create(user);
                _roleRepository.Use(session).AddToRole(user, Role.Public);
                session.Commit();
            }

или

using (var session = UnitOfWork.Begin())
            {
                session.Get<IUserRepository>().Create(user);
                session.Get<IRoleRepository>().AddToRole(user, Role.Public);
                session.Commit();
            }

Я небез ума от любого подхода;Я отмечу это как ответ, пока не получу лучшее предложение.

0 голосов
/ 01 ноября 2011

У Джулии Лерман есть несколько замечательных примеров использования Единицы работы с использованием Entity Framework.

В структуре сущностей она поддерживается в контексте, поэтому очень легко реализовать единицу работы.Основная проблема, которую я вижу, состоит в том, как вы управляете заказом.Пример: Таблица A и Таблица B

Таблица B имеет внешний ключ к Таблице A. Ваша единица работы должна знать о заказе, иначе произойдет ошибка.Я бы просто пошел с OR / M, как Nhibernate или EF.Это должно сделать намного проще.

...