Рабочий процесс: создание цепочки зависимостей с помощью шаблона Service Locator

Я пытаюсь правильно настроить зависимости в своем приложении Workflow. Кажется, лучший способ сделать это — использовать шаблон Service Locator, предоставляемый WorkflowExtensions.

В моем рабочем процессе используются два репозитория: IAssetRepository и ISenderRepository. У обоих есть реализации с использованием Entity Framework: EFAssetRepository и EFSenderRepository, но я бы хотел, чтобы оба использовали один и тот же DbContext.

У меня возникли проблемы с тем, чтобы оба использовали один и тот же DbContext. Я привык использовать IoC для внедрения зависимостей, поэтому я подумал, что мне придется внедрить DbContext в репозитории EF через их конструктор, но похоже, что это будет смешивать локатор службы и шаблон IoC, и я не мог найти простой способ добиться этого, поэтому я не думаю, что это путь вперед.

Я предполагаю, что мне нужно связать вызовы локатора службы? Чтобы конструктор моих репозиториев EF делал что-то вроде этого:

public class EFAssetRepository
{
    private MyEntities entities;

    public EFAssetRepository()
    {
        this.entities = ActivityContext.GetExtension<MyEntities>();
    }
}

Очевидно, что приведенное выше не будет работать, потому что ссылка на ActivityContext составлена.

Как я могу получить некоторую форму цепочки зависимостей, используя шаблон локатора сервисов, предоставленный для WF?

Спасибо, Ник


РЕДАКТИРОВАТЬ

Я разместил обходной путь для моей проблемы ниже, но я все еще не доволен им. Я хочу, чтобы активность кода могла вызывать metadata.Require‹>(), потому что она не должна знать, как загружаются расширения, она должна просто ожидать, что они есть. Как бы то ни было, мой вызов metadata.Require‹> остановит рабочий процесс, поскольку расширение похоже не загружено.




Ответы (1)


Кажется, один из способов сделать это — реализовать IWorkflowInstanceExtension в классе расширения, чтобы превратить его в своего рода составное расширение. Используя этот метод, я могу решить свою проблему следующим образом:

public class UnitOfWorkExtension : IWorkflowInstanceExtension, IUnitOfWork
{
    private MyEntities entities = new MyEntities();

    IEnumerable<object> IWorkflowInstanceExtension.GetAdditionalExtensions()
    {
        return new object[] { new EFAssetRepository(this.entities), new EFSenderRepository(this.entities) };
    }

    void IWorkflowInstanceExtension.SetInstance(WorkflowInstanceProxy instance) { }

    public void SaveChanges()
    {
        this.entities.SaveChanges();
    }
}

Самым большим недостатком этого способа является то, что вы не можете вызывать metadata.RequireExtension<IAssetRepository>() или metadata.RequireExtension<ISenderRepository>() в методе CacheMetadata CodeActivity, что является обычной практикой. Вместо этого вы должны вызвать metadata.RequireExtension<IUnitOfWork>(), но все еще можно сделать context.GetExtension<IAssetRepository>() в методе Execute() CodeActivity. Я предполагаю, что это связано с тем, что метод CacheMetadata вызывается до создания каких-либо экземпляров рабочего процесса, и если экземпляры рабочего процесса не созданы, фабрика расширений не будет вызываться, и, следовательно, дополнительные расширения не будут загружены в WorkflowInstanceExtensionManager, так что, по сути, он не будет знать о дополнительных расширениях, пока не будет создан экземпляр рабочего процесса.

person dark_perfect    schedule 02.10.2014