简体   繁体   中英

C# Dynamic Load/Unload Assemblies

I'm trying to load dynamically compiled assembly to other Appdomain and Unload it using Appdomain.Unload() method. I tried this:

  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);
                }
            }
        }
    }

where "IScript" is my CustomScript then, clicking button calls the compilation process and set RemoteLoader object:

 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);

    }

First, VS showed an exception that Scripts.MyCustomScript is not serializable. So I added [Serializable] to this and now VS shows an exception that "Scripts.MyCustomScript" can't be set as object of RemoteLoader.

You are trying to create an instance for Scripts.MyCustomScript and cast it as RemoteLoader . It is wrong. You want to create an instance of RemoteLoader from appDomainPluginB domain. So, you should specify the desired type for CreateInstanceAndUnwrap .

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

Then you can process and create instances from plugin types which is implemented from IScript .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM