C#动态加载/卸载程序集

时间:2018-01-23 16:55:02

标签: c# .net-assembly appdomain

美好的一天!我正在尝试将动态编译的程序集加载到其他Appdomain并使用Appdomain.Unload()方法卸载它。我试过这个:

  public class RemoteLoader : MarshalByRefObject
    {
        public void LoadAndExecute(string assemblyName)
        {
            Assembly pluginAassembly = AppDomain.CurrentDomain.Load(assemblyName);

            foreach (Type type in pluginAassembly.GetTypes())
            {
                if (type.GetInterface("IScript") != null)
                {
                    IScriptableComponent component = new DummyComponent();
                    var instance = (IScript)Activator.CreateInstance(type, null, null);
                    instance.Run(component);
                }
            }
        }
    }

其中“IScript”是我的CustomScript 然后,单击按钮调用编译过程并设置RemoteLoader对象:

 private void StartButton_Click(object sender, EventArgs e)
    {

        var compiledAssemblyPath = Path.Combine(Environment.CurrentDirectory, ScriptsDirectory, CompiledScriptsAssemblyName);

        var scriptFiles = Directory.EnumerateFiles(ScriptsDirectory, "*.cs", SearchOption.AllDirectories).ToArray();

        var scriptAssembly = Helper.CompileAssembly(scriptFiles, compiledAssemblyPath);

        AppDomain appDomainPluginB = AppDomain.CreateDomain("appDomainPluginB");

        RemoteLoader loader = (RemoteLoader)appDomainPluginB.CreateInstanceAndUnwrap(
           AssemblyName.GetAssemblyName(compiledAssemblyPath).Name,
           "Scripts.MyCustomScript");

        loader.LoadAndExecute(CompiledScriptsAssemblyName);
        AppDomain.Unload(appDomainPluginB);

    }

首先,VS显示Scripts.MyCustomScript不可序列化的异常。所以我添加了[Serializable],现在VS显示了一个异常,即“Scripts.MyCustomScript”不能设置为RemoteLoader的对象。你能帮我解决这个问题。 非常感谢!

1 个答案:

答案 0 :(得分:0)

您正在尝试为Scripts.MyCustomScript创建一个实例,并将其转换为RemoteLoader。这是错误的。您想要从RemoteLoader域创建appDomainPluginB的实例。因此,您应该为CreateInstanceAndUnwrap指定所需的类型。

RemoteLoader loader = (RemoteLoader)appDomainPluginB.CreateInstanceAndUnwrap(
    typeof(RemoteLoader).Assembly.FullName,
    typeof(RemoteLoader).FullName);

然后,您可以从IScript

实现的插件类型处理和创建实例