从动态导入的DLL

时间:2018-05-30 10:02:51

标签: c# entity-framework-core asp.net-core-2.0 system.reflection ef-core-2.0

我有一个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参数,我会得到相同的异常,但是带有消息&#34;没有为此对象定义无参数构造函数&#34;所以现在我很丢失,因为那里显然是一个建设者。

1 个答案:

答案 0 :(得分:2)

基本上问题是如何通过反射创建/获取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构造函数参数的全部目的是允许从外部配置db上下文(如数据库提供程序,连接字符串等),而不是在OnModelConfiguring内部进行自我配置。在哪种情况下,派生的db上下文将只具有无参数构造函数。

因此,最好创建DbContextOptionsBuilder<DefaultContext实例,使用Fluent APi对其进行配置,然后将Options属性(这是预期的DbContextOptions<DefaultContext类型)传递给{{1构造函数。 E.g。

DefaultContext