Правильный способ использования Unit of Work с единичным впрыском - PullRequest
2 голосов
/ 07 марта 2011

Я использую Unity, Entity Framework 4 с классами POCO, шаблон репозитория для DAL и сервисы для управления Business Logic. Я также хочу использовать Unit of Work, чтобы я мог объединять вместе CRUD-операции, которые я выполняю с различными сервисами, а затем фиксировать их все вместе.

Мой вопрос: как правильно внедрить механизм Unit Of Work в мое приложение, используя Microsoft Unity? Я понимаю, что могу поместить IUnitOfWork вместе с хранилищем в конструктор соответствующей службы, а затем, если указано сопоставление Unity, он автоматически инициирует соответствующие экземпляры, но таким образом я не передаю глобальную единицу работы, а скорее создаю новый экземпляр на каждом уровне, который не может быть разумным способом сделать это (на самом деле хранилище инициируется еще до обслуживания).

Чего мне не хватает? (Прилагается код конструктора, как я его сейчас написал, о сервисе и его репозитории).

U также понимает, что я могу использовать метод ParameterOverrides Unity, чтобы взять какой-то глобальный экземпляр Unit of Work (скажем, из моего файла aspx.cs) и передать его в службу, а затем в хранилище. Но это кажется немного отстойным. Это мой единственный вариант?

Спасибо

public class GenericRepository<T> : IUnitOfWorkRepository, IGenericRepository<T> where T : BaseEntity, IAggregateRoot
{

    private IUnitOfWork _uow;

    /// <summary>
    /// Returns the active object context
    /// </summary>
    private ObjectContext ObjectContext
    {
        get
        {
            return ObjectContextManager.GetObjectContext();
        }
    }

    public GenericRepository(IUnitOfWork uow)
    {
        _uow = uow;
    }

    //blahhhh...

    public void Add(T entity)
    {
        _uow.RegisterNew(entity, this);
    }

    public void Delete(T entity)
    {
        _uow.RegisterRemoved(entity, this);
    }

     //.....blah blah....

    public void PersistCreationOf(IAggregateRoot entity)
    {
        this.ObjectContext.AddObject(GetEntitySetName(), entity);
    }

    public void PersistUpdateOf(IAggregateRoot entity)
    {
        // Do nothing as EF tracks changes
    }

    public void PersistDeletionOf(IAggregateRoot entity)
    {
        this.ObjectContext.DeleteObject(entity);
    }
}

public class CategoryRepository : GenericRepository<XComSolutions.FB.Domain.Model.Entities.Category>, ICategoryRepository
{
    public CategoryRepository(IUnitOfWork uow)
        : base(uow)
    {   }
}

public class CategoryService : ICategoryService
{
    public int myID {get; set;}

    private ICategoryRepository _categoryRepository;
    private IUnitOfWork _uow;

    public CategoryService(ICategoryRepository categoryRepository,
        IUnitOfWork uow)
    {
        _categoryRepository = categoryRepository;
        _uow = uow;
    }

    public List<Category> GetAll()
    {
        return _categoryRepository.GetAll();
    }
}

Ответы [ 2 ]

3 голосов
/ 08 марта 2011

Определите IUnitOfWorkFactory и введите это в свои услуги:

public class Service
{
    private readonly IUnitOfWorkFactory factory;

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

    public void DoOperation()
    {
        using (UnitOfWork context = this.factory.CreateNew())
        {
            this.DoSomeStuff(context);
            this.DoMoreStuff(context);

            context.SubmitChanges();
        }
    }
}
0 голосов
/ 11 марта 2011

Я думаю, что вам нужно определить фабрику единиц работы. Вы регистрируете эту фабрику в своем контейнере DI и разрешаете для этой фабрики каждый раз, когда вам нужна ваша единица работы. Затем вы получаете единицу работы с завода, работаете с ней и отпускаете. Вы часто увидите, что вам нужна ваша единица работы в рамках одного метода или одного класса. В этой статье обсуждается шаблон единицы работы в связи с Entity Framework: http://msdn.microsoft.com/en-us/magazine/dd882510.aspx

...