如何通过反射在另一个项目中引用EF配置?

时间:2015-11-16 20:10:49

标签: c# entity-framework reflection

我正在尝试创建一个控制台应用程序,用于为自动化目的生成SQL迁移脚本 - 生成的相同脚本:

Update-Database -Script

从包管理器控制台。

在我创建的控制台应用程序中,如果直接引用具有DBMigrationsConfiguration的DLL,我可以生成脚本。

例如,这有效:

using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
using System.IO;
using TAPS.Infrastructure.Migrations;

namespace msg
{
    class Program
    {
        static void Main(string[] args)
        {

            var migrator = new DbMigrator(new Configuration());
            var scriptor = new MigratorScriptingDecorator(migrator);
            var sql = scriptor.ScriptUpdate(null, null);            
            File.WriteAllText(@"c:\script.sql", sql);
        }
    }
}

请注意,我有一个直接引用DLL,一个using语句,我使用一个新语句来实例化Config对象。

现在,如果我尝试通过反射做到这一点,我会从行中找回null:

DbMigrationsConfiguration configuration = (DbMigrationsConfiguration)assembly.CreateInstance("TAPS.Infrastructure.Migrations, Configuration");            

完整的代码示例跟随我试图通过反射工作:

using System;
using System.Data.Entity.Migrations;
using System.Data.Entity.Migrations.Infrastructure;
using System.IO;
using System.Reflection;

namespace msg
{
    class Program
    {
        static void Main(string[] args)
        {
            Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes(@"C:\DLLPath\TAPS.Infrastructure.dll"));
            DbMigrationsConfiguration configuration = (DbMigrationsConfiguration)assembly.CreateInstance("TAPS.Infrastructure.Migrations, Configuration");            
            var migrator = new DbMigrator(configuration);
            var scriptor = new MigratorScriptingDecorator(migrator);
            var sql = scriptor.ScriptUpdate(null, null);            
            File.WriteAllText(@"c:\script.sql", sql);
        }
    }
}

配置变量返回null。

2 个答案:

答案 0 :(得分:1)

如果配置类型在TAPS.Infrastructure.Migrations命名空间中,您需要使用反射来实现它,您使用的语法是错误的。

var foo = assembly.CreateInstance("TAPS.Infrastructure.Migrations.Configuration");   

尝试此操作循环遍历已加载程序集中的所有类型,名称必须匹配。

foreach (var type in assembly.GetTypes())
{
    Console.WriteLine(type);
}

答案 1 :(得分:0)

此代码修复了它:

class ProxyDomain : MarshalByRefObject
{
    public Assembly GetAssembly(string assemblyPath)
    {
        try
        {
            return Assembly.LoadFrom(assemblyPath);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException(ex.Message);
        }
    }
}

来自@shytikov的回答:

How to Load an Assembly to AppDomain with all references recursively?