-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
MEF on .NET Core 2.1 fails to load plugins from folder , but works well with .NET Framework 4.6.1 #30978
Comments
Added detailed exception message |
Update-To rule out issues with MEF, I used Assembly.LoadFrom and I was able to repro the above problem on .NET CoreI added a second Program.cs to the projects Code
Observations .NET Framework has no problems in loading the plugin NewtonSoft v9 followed by loading the plugin which references NewtonSoft v12. .NET Core succeeds loading the plugin which references NewtonSoft v9, but fails when it also tries to load the plugin with NewtonSoft v12.
As per my experience with .NET Framework, side by side loading was never so much of an issue. Have things changed with .NET Core? Where am I going wrong? |
Duplicate of https://github.com/dotnet/coreclr/issues/26861 |
Hi @jkotas , Just wanted to verify with you that the problem in this issue concerns loading of plugin assemblies via lazy loading of Managed Extensibility Framework and that you concur that these two issues are indeed connected to the same underlying problem. (I think they are, but I am not the expert here). Just to let you know MEF has been working wonderfully for us .NET 4.6.1. We have had no issues in loading plugins and their side by side dependencies from various folders. MEF has indeed been a boon in modularizing our back end document parsing application which was otherwise becoming a monolith. Thank you, |
Your are right. The two issues are related, but not exactly same. |
This problem is caused by |
@jkotas do you already have insight into the fix here? |
If we want to fix it, the fix would be about implementing proper loading context isolation using AssemblyLoadContext in MEF. Note that .NET Framework did not provided a proper plugin isolation either in this case. A more complex plugins scenario would fail with the same problem in .NET Framework as well. |
From experience, using MEF in .NET Framework appears to provide exactly this level op plugin isolation. I recently created a test where I load different versions of the same plugin, each plugin version, in turn, using different versions of a core dependency shared between the plugin and the host application without any issues. Host App -> Plugin V1 -> Core Dependency V1 Duplicating this using MEF in .NET core has proven impossible thus far. I am now experimenting using AssemblyLoadContext directly, but find the API to be poorly documented. |
Experimenting with AssemblyDependencyResolver and Resolving eventApproachI was exploring if the issue of loading the correct dependency can be sorted out in the Resolving event of the AssemblyLoadContext class. We have the PluginV9 and PluginV12 and their dependencies NewtonSoft.Json(9) and Newtonsoft.Json(12) in their respective folders.
Challenges
Is there an alternative?I would be happy if the designers of .NET Core can propose an alternative. I think the scenario is important. |
The |
cc @vitek-karas |
Thank you @jkotas for pointing me to the sample. I have made significant progress. I have derived inspiration from this sample and finally able to have the Newtonsoft v9 and Newtonsoft v12 loaded on demand. BackgroundWe have the PluginV9 and PluginV12 and their dependencies NewtonSoft.Json(9) and Newtonsoft.Json(12) in their respective folders. Initial steps
What is the difference - Assembly.LoadFile vs Assembly.LoadFromI was using Therefore , I used Code snippet - Resolving event
Challenges and further thoughts
Sample codehttps://github.com/sdg002/MEFFwkCoreComparison Thanks, |
I am hoping that the above approach will work with the DirectoryCatalog of Managed Extensibilty Framework. I am yet to try that out. The property Add handler for |
.NET Core assembly loader ignores strong names. This was done to enable migration of the ecosystem away from strong naming that is endless source of pain.
This situation does not happen in practice. The situations where strong names cause problems are multiple orders of magnitude more common.
Does the .NET Framework equivalent of what you are trying to have the same closest matching version policy? This policy will lead to unpredictable behaviors in more complex systems (e.g. a new plugin is added to the system, and unrelated plugin breaks). My recommendation would be to avoid this version guessing at runtime. |
Understood. .NET Core assembly loader ignores strong names completely. I was not aware of this change. Thank you. Coming back to the original problem, please help me understand, if the aforementioned behaviour is the reason for I am guessing that the loader stops further discover when it finds that there is an already loaded assembly whose file name matches Newtonsoft.json.dll . |
Right. The loader does lookup based on the simple names only. |
* Added an optional AssemblyLoadContext to the AssemblyCatalog. * Added an option to the DirectoryCatalog to isolate the assemblies inside this directory. Fixes dotnet#30978
* Added an optional AssemblyLoadContext to the AssemblyCatalog. * Added an option to the DirectoryCatalog to isolate the assemblies inside this directory. Fixes dotnet#30978
* Added an optional AssemblyLoadContext to the AssemblyCatalog. * Added an option to the DirectoryCatalog to isolate the assemblies inside this directory. Fixes dotnet#30978
Due to lack of recent activity, this issue has been marked as a candidate for backlog cleanup. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will undo this process. This process is part of our issue cleanup automation. |
Issue Title
I have 2 plugin class libraries which reference different version of the Newtonsoft.Json package. Console EXE on .NET Fwk has no problems in loading both of the plugins and invoking the 2 different versions of Newtonsoft.Json simultaneously.
However, console EXE on .NET Core 2.1 will fail on the second plugin. It is almost as though .NET Core is unable to load 2 different versions of the same assembly.
My initial view is that this is less to do with Managed Extensibility Framework . The root cause most probably lies with how .NET Core is designed to load multiple versions of referenced assemblies. In this case the referenced assembly is NewtonSoft.
General
I have two .NET Standard 20 class libraries (PluginNewtonsoftv12) and (PluginNewtonsoftv9) which implement an interface defined in the class library project Contracts.
I have two EXE projects - ConsoleAppNetCore and ConsoleAppNETFramework which use the DirectoryCatalog of Managed Extensibility Framework to discover and load the plugins.
The output of the projects PluginNewtonsoftv9 and PluginNewtonsoftv12 are copied to a plugins folder using a post build step. This is the out folder in the project PluginsDeliveryFolder. Both the plugin projects have the attribute CopyLocalLockFileAssemblies to ensure that all dependent assemblies get copied over to their respective folders.
What is important that EXE should have no compile time knowledge of the plugin library except for the contractual interfaces.
Solution structure
Steps to reproduce - Framework
Steps to reproduce - NET Core
Screen capture of failure when using .NET Core
Exception message when using .NET Core
Screen capture of success when using .NET Framework
Source code
https://github.com/sdg002/MEFFwkCoreComparison
Summary
,NET Framework works as expected. It is able to load the 2 versions of Newtonsoft side by side. However, .NET Core is unable to cope with the 2 versions side by side. Is this a limitation of .NET Core?
The text was updated successfully, but these errors were encountered: