Регистрация нескольких экземпляров DbContext при запуске для использования в универсальном репозитории - PullRequest
0 голосов
/ 08 июля 2019

Я пытаюсь создать универсальный репозиторий, который принимает 2 универсальных типа, например

public class EfRepository<T, TS> : IAsyncRepository<T,TS> where T : BaseEntity
                                                           where TS : DbContext
    {
..........
}

, и в моем файле startup.cs у меня есть обычное отображение:

services.AddScoped<DbContext, ConfigDbContext>();

Как теперь я могу добавить другое отображение в DbContext?Я попытался добавить еще одно сопоставление между DbContext и другим контекстом, который я создал, но он всегда использует только первое сопоставление.

У меня есть несколько баз данных, которые мне нужно использовать, и в идеале хотелось бы иметь DbContext для каждой, но я не вижу способа иметь несколько отображений DI.

В моем классе EfRepository классследующие исключения кода, когда я добавляю дополнительный DbContext в свой код и использую его:

protected readonly DbContext _dbContext;
        public EfRepository(DbContext dbContext)
        {
            this._dbContext = (TS)dbContext;
        }

Исключение невозможно преобразовать из Type1 в Type2, и я знаю, что это потому, что DbContext привязан к Type1 в моем запуске.cs.

Как я могу (если возможно) использовать несколько DbContext в общем виде?

1 Ответ

2 голосов
/ 08 июля 2019

Это не то, как вы регистрируете DbContext, что является источником вашей проблемы.Правильный метод:

services.AddDbContext<ConfigDbContext>(o =>
    o.UseSqlServer(Configuration.GetConnectionString("Foo")));

Сделано правильно, добавление еще одного точно такое же:

services.AddDbContext<SomeOtherContext>(o =>
    o.UseSqlServer(Configuration.GetConnectionString("OtherConnectionString")));

Затем, какой из них будет извлечен, зависит от того, что вы вводите, а что да, делаетозначает, что вам нужно указать фактический тип, который вы хотите внедрить, а не DbContext в общем.Однако это может быть сделано только одним производным классом.Другими словами, вы можете сохранить имеющийся у вас код (хотя вы не должны приводить контекст) и просто сделать:

public class FooRepository : EFRepository<Foo, ConfigDbContext>
{
    public FooRepository(ConfigDbContext context)
        : base(context) {}
}

Вы можете оставить его повышенным до DbContext, так как вам не нужнофактический тип, чтобы сделать вещи EF.Чтобы добраться до DbSet s, вы можете использовать общий Set<T>:

var foos = _dbContext.Set<Foo>();

И теперь, со всем, что сказано, выбросить все это.Совершенно недопустимо использовать шаблон репозитория с ORM, подобным EF.EF уже реализует шаблоны хранилища и единицы работы.DbContext - это ваша единица работы, а каждый DbSet - это хранилище.Добавление дополнительного слоя поверх всего этого не делает ничего, кроме проблем с обслуживанием и дополнительной энтропии в вашем коде, и, честно говоря, создание репозитория / единицы работы, которая хорошо работает с EF, настолько старается, что оказывается невозможным, поэтому чаще всего, чем нет.вы просто собираетесь использовать EF, чтобы сделать его менее эффективным и трудным в использовании.

Использование ORM, такого как EF, означает использование стороннего DAL.Это все.Там нет необходимости создавать свой собственный DAL в этот момент, потому что вы его на аутсорсинг.Я не уверен, почему так много людей зацикливаются на этом.Когда вы в последний раз создавали свою собственную инфраструктуру маршрутизации или свой собственный препроцессор шаблонного представления.Никогда.Вы просто сторонние библиотеки для этого (фреймворка), так почему же проблема заключается в использовании сторонней библиотеки для вашего DAL?

Затем вы задаетесь вопросом, как насчет абстрагирования зависимости EF.Ну, во-первых, если вы думаете, что можете переключить ORM когда-нибудь в будущем, вы не будете.Такого просто не бывает.Вы будете переписывать все приложение с нуля.Во-вторых, шаблон хранилища даже не достигает этого.У вас все еще есть зависимость EF, которая всплывает вплоть до фронтального приложения.Обойти это невозможно.

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

...