Как внедрить dbcontext с помощью StructureMap и WebApi2

Я хотел бы внедрить свой dbcontext в свои службы в проекте web api 2. Но я немного не уверен, как это сделать. Я прочитал документацию, но жизненные циклы, области действия, запросы, вложенные контейнеры... все это оставляет меня немного неуверенным. Я собрал следующий код из моего лучшего понимания. После установки пакета Nuget StructureMap.WebApi2 я приступил к обновлению SM с версии 3 до версии 4, а также SM.MVC5 с версии 3 до версии 4.

Следующий код, по-видимому, имеет желаемый эффект использования одного dbcontext для каждого http-запроса (я думаю, это то, что я хочу... я так запутался в областях), чтобы один и тот же dbcontext использовался для всех служб во время транзакции пользователей, и затем удаляется, когда транзакция (http-запрос) закрывается. Но внешность не всегда правильная.

IoC.cs

    public static IContainer Initialize()
    {
        var container = new Container(_ =>
        {
            _.AddRegistry<DefaultRegistry>();
            _.ForConcreteType<MyDbContext>().Configure.ContainerScoped();
        });
        DomainEvents.Initialize(container);
        return container;
    }}

DefaultRegistry.cs:

    public DefaultRegistry()
    {
        var mapperConfig = new MapperConfiguration(cfg =>
        {
            cfg.AddProfile(new Common.Map.MapProfile());
            cfg.CreateMissingTypeMaps = true;
        });
        var mapper = mapperConfig.CreateMapper();
        For<IMapper>().Use(() => mapperConfig.CreateMapper());
        For<MyDbContext>().Use(()=> new MyDbContext());

        Scan(
            scan =>
            {
                scan.AssemblyContainingType<ServiceBase>();
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.ConnectImplementationsToTypesClosing(typeof(IHandle<>));
            });
    }

Пакет Nuget StructureMap.WebApi2 создал несколько других файлов для подключения разрешения и вложенных контейнеров, но я не рассматриваю их в этом вопросе для краткости.




Ответы (1)


Взгляните на Mehdime DbContext Scope Factory/Locator: https://github.com/mehdime/DbContextScope и у него в блоге есть немного информации об этом. (ссылка в описании проекта.) Там есть форки, обновленные до последних версий EF.

Я обнаружил, что это отличная рабочая единица-оболочка для контекстов EF, не беспокоясь о внедрении или передаче этих контекстов напрямую.

Проблема с контейнерами IoC и внедрением конструктора заключается в том, что если вы регистрируете свой DBContext, это означает, что трудно работать с такими вещами, как единица работы в рамках запроса, не являясь по существу всей областью запроса. Область DbContext решает эту проблему, регистрируя фабрику областей и локатор областей в своем контейнере. Код, управляющий Scope (единицей работы), будет использовать Scope Factory для инициализации области контекста для ваших DbContexts. Код, работающий с DbSets и т. д. в DbContext, использует ContextScopeLocator, чтобы получить их UoW/w, это DbContext и наборы.

person Steve Py    schedule 09.06.2017
comment
Я смотрел на это раньше, но посмотрю еще раз. Моя первая реакция, однако, заключается в том, что, поскольку я нахожусь в веб-среде, большинство моих применений будет как один uow для каждого запроса. До сих пор я не обнаружил необходимости охватывать второй dbcontext в том же запросе. Это может быть хорошим альтернативным предложением, которое я в конечном итоге приму, но, к сожалению, оно не отвечает на мой вопрос о том, правильный ли мой код выше. - person chadb; 09.06.2017