Реализация UnitOfWork - PullRequest
       19

Реализация UnitOfWork

5 голосов
/ 05 февраля 2011

Мне удалось реализовать небольшую классную единицу работы для работы с структурой сущностей.

Я придумал ..

public class UnitOfWork : IUnitOfWork
    {
        private Database _database;
        private IDatabaseFactory _databaseFactory;

        private DbTransaction transaction;

        public UnitOfWork(IDatabaseFactory databaseFactory)
        {
            _databaseFactory = databaseFactory;
            _database = Database;

            transaction = _database.Database.Connection.BeginTransaction();
        }

        public Database Database
        {
            get { return _database ?? (_database = _databaseFactory.Get()); }
        }

        public void Dispose()
        {
            try
            {
                _database.SaveChanges();
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
            }
        }
    }

Я почти уверен, что все сейчас завидуют этой единице работы. (Шучу)

Но у меня небольшая проблема с дизайном в этом слое обслуживания.

public class JournalService : IJournalService
    {
        IJournalRepository _journalRepository;

        public JournalService(IJournalRepository journalRepository)
        { 
            _journalRepository = journalRepository;
        }

        public void AjouterJournal(Journal j)
        {
           [B]using (IUnitOfWork uow = new UnitOfWork())[/B]
            {
                var journal = new Journal();
                journalRepository.AddJournal(journal);

            }
        }
    }

Проблема в том, что единице работы требуется внедрение базы данных, поэтому я не могу создать ее экземпляр. Я не могу предоставить единицу работы непосредственно на уровне обслуживания, потому что это не имеет смысла, поскольку единица работы должна быть одноразовой.

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

Я мог бы внедрить IDatabaseFactory в свой сервисный слой, но идея в том, чтобы не использовать его там. На самом деле сервисный уровень не должен знать об этом.

Как насчет фабрики UnitOfWork?

Любые идеи или предложения о том, как я могу это исправить?

Спасибо.

1 Ответ

7 голосов
/ 06 февраля 2011

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

Другое дело, что эта реализация применима только для простых операций CRUD.В более сложных сервисах вы в итоге составите несколько операций (возможно, из нескольких сервисов), каждая из которых будет работать с UnitOfWork.Вызов нескольких SaveChanges (и транзакций) в одной бизнес-операции, вероятно, не является тем, что вы обычно хотите - в таком случае вы хотите вызывать SaveChanges только один раз из какой-либо службы верхнего уровня или из вызывающей стороны службы.Типичный сценарий состоит в том, что одна бизнес-операция имеет одну единицу работы с одной транзакцией, но вы можете выполнять множество операций службы как часть этой бизнес-операции.

Еще одним следствием является создание ваших репозиториев.Возможно, им нужен доступ к базе данных, не так ли?Таким образом, вы, вероятно, уже внедрили UoW в конструктор хранилища.Если вы сделаете это, вы вообще сможете избежать связи между UoW и базовыми услугами.

...