简体   繁体   中英

Unload Assemblies loaded by Ninject

I have a build a Plugin-System using Ninject. I load the Plugins like this:

private void LoadPlugIns()
{
    lock (_syncRoot)
    {
    Kernel.Bind(x => x.FromAssembliesInPath(AppDomain.CurrentDomain.BaseDirectory)
        .SelectAllClasses().InheritedFrom<IRenderPlugIn>()
        .BindAllInterfaces()
        .Configure(b => b.InSingletonScope()));
    RenderPlugins = Kernel.GetAll<IRenderPlugIn>();
    if (RenderPlugins != null && RenderPlugins.Count() > 0)
        Logger.Info("{0} Render-Plugins geladen.", RenderPlugins.Count());
    else
        Logger.Warn("Keine Render-Plugins geladen.");
    }
}

Now I want to be able to update the Plugins while the application is running, I am unloading all Plugins like this:

private void UnloadPlugIns()
{
    lock (_syncRoot)
    {
        Logger.Trace("Entlade Render-Plugins.");
        var plugins = _renderPlugins;
        RenderPlugins = null;
        Kernel.Unbind<IRenderPlugIn>();
        if (plugins != null)
            foreach (var plugin in plugins)
                Kernel.Release(plugin);
        else
            Logger.Warn("Es waren keine Render-Plugins geladen.");
        Logger.Info("Alle Render-Plugins entladen.");
    }
}

My problem is that the Plugin-assemblies are still locked by the process, so that I am not able to delete or overwrite them.

I have read some stuff about AppDomains and ShadowCopyFiles, I think that could help. But when using an AppDomain for my Plugin-Manager I have to deal with the limited lifetime of the remoting objects, which will cause much headache.

Is there a way I can do this with Ninject?

[Edit] Ninject cannot unload an assembly.

You are correct to look into AppDomains. You cannot unload a type or assembly, so your Kernel.Release does not remove the types from you application, your application simply does not reference it.

You can only unload an AppDomain. With this approach you have to be cognizant that you are crossing a boundary. You can marshal your objects by reference MarshalByRefObjects which gives you a reference to the object in another domain. If you can serialize ( serialized ) your objects, you will run into the same problem you are running into now because the objects will be deserialized in the master domain. So do not pass any objects across domains that you do not want to lock into your host AppDomain.

You will need to provide an interface that both the host AppDomain and the hosted AppDomains know about.

I suggest you look into the MS Add-In Framework (MAF).

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