Entity Framework: внедрение зависимостей в сущности, когда другие варианты проблематичны

Я работаю над большим корпоративным проектом C#, который имеет серьезные архитектурные проблемы. Одна из этих проблем заключается в том, что статические ссылки на контейнер StructureMap повсюду (статический локатор службы). В качестве первого шага к исправлению ситуации мы передаем контейнер в конструкторы и удаляем ссылки на статические контейнеры.

К сожалению, в сущностях, созданных Entity Framework, есть вызовы статического контейнера. Передача всех этих зависимостей клиентам этих сущностей невозможна прямо сейчас из-за того, как часто это происходит, и из-за масштабов изменений. Наша цель — удалить статический контейнер, и внесение такого количества изменений не будет разрешено руководством.

Вместо этого я хотел бы внедрить контейнер в объекты, когда они создаются Entity Framework, есть ли способ сделать это?

Заранее спасибо :)


person nash    schedule 02.03.2017    source источник
comment
Удаление зависимостей из сущностей и переход на внедрение зависимостей из локатора сервисов являются частью плана, но шаг за шагом...   -  person nash    schedule 03.03.2017


Ответы (1)


Помнится, несколько лет назад я где-то читал, что сервисы можно внедрить в сущности через конструктор, но сейчас не нашел, может, читал про IDbDependencyResolver, который служит другой цели.

В качестве временного решения я бы предложил пометить сущности интерфейсом типа IHaveServiceLocator и использовать событие ObjectMaterialized.

public interface IHaveServiceLocator
{
    IServiceLocator ServiceLocator { get; set; }
}

И тогда место, где вы создаете dbContext, должно иметь доступ к локатору службы, чтобы вы могли установить его для созданных объектов.

((IObjectContextAdapter)dbContext).ObjectContext.ObjectMaterialized += (s, e) =>
{
    var entity = e.Entity as IHaveServiceLocator;

    if (entity != null)
    {
        entity.ServiceLocator = structureMapServiceLocator;
    }
}
person Andrii Litvinov    schedule 03.03.2017
comment
Спасибо, работает как шарм. Приятно иметь возможность просто реализовать интерфейс и внедрить контейнер. - person nash; 07.03.2017
comment
это выглядит вполне разумно; однако есть люди, которые будут кричать servicelocator, ах! анти-шаблон!. что бы вы им сказали? - person jenson-button-event; 26.11.2017
comment
@ jenson-button-event Я определенно согласен с тем, что локатор сервисов является анти-шаблоном, и лично почти никогда его не использую. Но иногда это делает работу и избавляет от переписывания всей базы кода, как этот вопрос. - person Andrii Litvinov; 26.11.2017