Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make plugins unloadable #16

Open
natemcmaster opened this Issue Oct 25, 2018 · 8 comments

Comments

Projects
None yet
5 participants
@natemcmaster
Copy link
Owner

natemcmaster commented Oct 25, 2018

This will require .NET Core 3.0 and up, which has added libraries to make assembly load contexts unloadable.

See dotnet/coreclr#552, dotnet/coreclr#18476, dotnet/corefx#14724, and https://github.com/dotnet/coreclr/projects/9

@per-samuelsson

This comment has been minimized.

Copy link
Contributor

per-samuelsson commented Oct 31, 2018

Should be pretty straightforward to implement as well as it seem: sample.

Only 3.0 need to become available. 😎

@FrankDoersam

This comment has been minimized.

Copy link

FrankDoersam commented Nov 5, 2018

Thank you for the info. However, after unloading, the DLL could not be deleted from the directory? Have I possibly ignored something?

Thanks in advance.
Yours sincerely
Frank Dörsam

Code:

 class SimpleUnloadableAssemblyLoadContext : AssemblyLoadContext
    {
        public SimpleUnloadableAssemblyLoadContext()
           : base(isCollectible: true)
        {
        }

        protected override Assembly Load(AssemblyName assemblyName) => null;
    }

    class Program
    {
        private static void ExecuteAssembly(Assembly assembly)
        {
            MethodInfo entry = assembly.EntryPoint;
            foreach (Type type in assembly.GetTypes())
            {
                Console.WriteLine(type.FullName);
            }
            Console.WriteLine("ok");

        }

        static void Main(string[] args)
        {
            AssemblyLoadContext tt = new SimpleUnloadableAssemblyLoadContext();
            tt.LoadFromAssemblyPath(@"C:\Lokale Daten\AppDomainUnload\ConsoleApp1\bin\Debug\netcoreapp3.0\Plugin\Plugin1.dll");

            tt.Unload();
            Console.ReadKey();
        }

        private static void Context_Unloading(AssemblyLoadContext obj)
        {
            Console.WriteLine("Unloading");
        }
    }
@natemcmaster

This comment has been minimized.

Copy link
Owner Author

natemcmaster commented Nov 5, 2018

If you are not able to delete a dll after unloading its load context, it is probably a bug in .NET Core 3. Checkout https://github.com/dotnet/coreclr/projects/9 to see if this is a known issue. If not, open a new bug on dotnet/coreclr.

@Apollo3zehn Apollo3zehn referenced this issue Dec 14, 2018

Open

Nuget plugin manager: Remaining tasks #140

8 of 20 tasks complete

@natemcmaster natemcmaster added this to the .NET Core 3.0 milestone Jan 4, 2019

@HamedFathi

This comment has been minimized.

Copy link

HamedFathi commented Jan 9, 2019

@natemcmaster,

Based on .NET Core 3 preview 1

image

Is this issue possible to solve now or need the next versions?

@natemcmaster

This comment has been minimized.

Copy link
Owner Author

natemcmaster commented Jan 9, 2019

Yes. 3.0 preview 1 should have AssemblyLoadContext.Unload in it.

I don't think there is any use for MetadataLoadContext in this project. That API is more about "reflection-only" loading. It's similar to AssemblyLoadContext, but not exactly the same.

@natemcmaster natemcmaster referenced a pull request that will close this issue Feb 6, 2019

Open

Make plugins unloadable #31

@natemcmaster

This comment has been minimized.

Copy link
Owner Author

natemcmaster commented Feb 6, 2019

Initial implementation #31.

Usage

Unloadable plugins is supported in .NET Core 3.0 Preview 2 and newer. To unload a plugin, dispose the loader.

var loader = PluginLoader.CreateFromAssemblyFile(
                    pluginDll,
                    sharedTypes: new [] { typeof(IPlugin) });
// do stuff

loader.Dispose(); // this triggers an unload
@dazinator

This comment has been minimized.

Copy link

dazinator commented Feb 6, 2019

Any ideas whether this would allow asp.net core application parts to be unloaded (then reloaded from new assemblies) ? I asked / raised an issue but the response was its not on asp.net core roadmap: aspnet/AspNetCore#7219 - I wonder if you have had any thoughts around this?

@natemcmaster

This comment has been minimized.

Copy link
Owner Author

natemcmaster commented Feb 7, 2019

It might. Unloading is very new and I haven't played with it enough to try this out. Calling .Dispose() on a plugin doesn't guarantee it will be immediately unloaded. If managed memory still has pointers to something from the plugin, the plugin won't be cleaned up by garbage collection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.