Загрузить EF Core 2 DbContext из динамически импортированной DLL - PullRequest
0 голосов
/ 30 мая 2018

У меня есть DbContext, который мне нужен для динамической загрузки из DLL, так как контекст Db изменится и его нужно будет редактировать во время работы приложения, однако я не могу создать экземпляр этого контекста, как мне кажется,передать в контекстные параметры.этот код приведен ниже.

Assembly reporting = Assembly.LoadFile(pathString);

        var defaultContext = reporting.GetType("Reporting.DefaultContext");
        var dbContext = Activator.CreateInstance(defaultContext, new
 object[] { /*need to pass in the contructor here*/ }) as DbContext;

и мой скомпилированный контекст довольно стандартный, модифицированная версия этого ниже для справки

public class DefaultContext : DbContext
{
    public DefaultContext(DbContextOptions<DefaultContext> options)
        : base(options)
    { }

    public virtual DbSet<Student> Students { get; set; }
    public virtual DbSet<Course> Courses { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>().ToTable("Students ", "core")
            .AllProperties().ForEach(x => x.IsRequired());

        modelBuilder.Entity<Course>().ToTable("Courses", "core")
            .AllProperties().ForEach(x => x.IsRequired());
    }
}

Я довольно неопытен, когда дело доходит до размышлений -так что вопросы на самом деле таковы:

Это лучший способ попытаться достичь этого или я должен создать метод для вызова в DLL для возврата контекста?

Если нет, как мне поступитьо прохождении через экземпляр DbContextOptions, когда у меня нет контекста?

Примечание: это проект Asp.Net Core 2.0 MVC.

РЕДАКТИРОВАТЬ: при передаче пустого массива obj в экземпляр create, как показано ниже, я получаю исключение отсутствующего метода (конструктор не найден)

var dbContext = Activator.CreateInstance(defaultContext, new object[] { new object[0] }) as DbContext;

Тогда как, если я не передам второйПараметр obj Я получаю то же исключение, но с сообщением «Для этого объекта не определен конструктор без параметров», так что теперь я довольно растерялся, поскольку явно есть строитель.

1 Ответ

0 голосов
/ 30 мая 2018

В основном вопрос заключается в том, как создать / получить DbContextOptions<DefaultContext> экземпляр с помощью отражения.Вы можете сделать это, сначала создав универсальный тип через MakeGenericType, а затем использовать этот тип в качестве аргумента для Activator.CreateInstance.

Таким образом, имея

var dbContextType = reporting.GetType("Reporting.DefaultContext");

что-токак это:

var optionsType = typeof(DbContextOptions<>).MakeGenericType(dbContextType);
var options = (DbContextOptions)Activator.CreateInstance(optionsType);
var dbContext = (DbContext)Activator.CreateInstance(dbContextType, options);

Однако вся цель аргумента конструктора DbContextOptions<TDbContext> options состоит в том, чтобы позволить настраивать контекст БД (например, поставщик базы данных, строку подключения и т. д.) извне, а не самоконфигурировать внутриOnModelConfiguring, в этом случае ваш производный контекст БД будет просто иметь конструктор без параметров.

Следовательно, было бы лучше создать экземпляр DbContextOptionsBuilder<DefaultContext, использовать Fluent APi для его настройки, а затем передать свойство Options (который предназначен DbContextOptions<DefaultContext тип) для DefaultContext конструктор.Например,

var optionsBuilderType = typeof(DbContextOptionsBuilder<>).MakeGenericType(dbContextType);
var optionsBuilder = (DbContextOptionsBuilder)Activator.CreateInstance(optionsBuilderType);

string connectionString = ...;
optionsBuilder.UseSqlServer(connectionString);

var dbContext = (DbContext)Activator.CreateInstance(dbContextType, optionsBuilder.Options);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...