Closed ShankarBUS closed 1 year ago
What is your in your csproj file? SqlClient is one of the test cases in this project. https://github.com/natemcmaster/DotNetCorePlugins/blob/ad66725684cc1c9b293146bd215749a6f651cf10/test/TestProjects/SqlClientApp/SqlClientApp.csproj. Make sure you use netcoreapp, not netstandard.
Yes I use netcoreapp3.1 and not netstandard. WPF needs atleast .NET core 3.0
The error won't show when there are no shared types or assemblies
None of my projects/their dependencies depend on System.Data.SqlClient. I checked all of their *.deps.json. What should I do?
Can you share your csproj files? Perhaps you are pulling this dependency somehow transitively.
Hey @natemcmaster, I have the reproduceable repo here ShankarBUS/ExtensibilityTest
commit 34cc7cd will throw a System.IO.FileNotFoundException saying
"Could not load file or assembly 'System.Data.SqlClient, Version=4.6.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'. The system cannot find the file specified."
while commit 1ef9c3e will work (how?) since the UseWPF tags and AssemblyInfo.cs has been removed from those projects.
You can see that those projects are just basic libs with no dependencies and if I have UseWPF (with "AssemblyInfo.cs"), they don't work π€ with this lib
Should I update this issue to be This library doesn't work with WPF libraries?
I am trying to solve the same problem. But trying your repo I have no problems in its execution, the SqlClient error does not appear. Tested with Visual Studio Preview 16.7.0 Preview 2.0
Changing UseWPF tags has no difference.
Actually this problem appeared in the initial tests that I made of this library and then I managed to solve it, with which I took advantage of its use, but I am trying to remember what the solution path was. Since we came from using MEF for the implementation of plugins, what was missing in the McMaster library was detecting the available plugins without loading the assemblies, so implement the metadata reading of the files through attributes, with which a list of the available plugins and their characteristics is obtained to be able to select them from a categorized list, thus obtaining the path to the assembly that contains it and the name of the plugin. With this data the creation of the instance is done with the current library, which is where the infamous SqlClient error appears.
Output Window shows My Extension load
What's the .NET Core SDK you're using. It may be rooting from the sdk maybe. Mine is 3.1.400-preview-015151
This is our scenario. At left the breakpoint in the exception generated. Ar right the plugin width the Export Attributes at MEF style
Still experiencing the bug π
5.0.100-preview.5.20279.10
No I asked the .NET Core 3.1 SDK version installed in your system that you used to build my repo
3.1.400-preview-015151
One of the errors I found in your repo is in debug mode in output path for MyExtension dlls storage. Must be "Debug" instead "Release". Verifiy it
You are right.
return PluginLoader.CreateFromAssemblyFile( dllloc, isUnloadable: true, sharedTypes: new Type[] { / typeof(ExtensionBase), typeof(IUIItem) // Not neccessary / });
Also works, when the list must be empty.
One of the errors I found in your repo is in debug mode in output path for MyExtension dlls storage. Must be "Debug" instead "Release". Verifiy it
..\ExtensibilityTest\bin\Debug\netcoreapp3.1\ExtensibilityTest.exe ..\ExtensibilityTest\bin\Debug\netcoreapp3.1\Extensions\netcoreapp3.1\MyExtension.dll
They are both in the same folder π€
Hmmm... This branch seems to work. I removed this
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
from the AssemblyInfo.cs and the UseWPF tag is still present. What's happening?
Sorry, may be my mistake.
I am trying loader without types in our solution. No error happens, and no plugin is loaded, what is correct. Seems to be that error happens in assembly loading.
Evidently are not clear differences between your environment and our.
Your instance loads all the plugins availables in the assembly withour type defined. and our instance don't loads without a type but fires error alt loading.
One of the errors I found in your repo is in debug mode in output path for MyExtension dlls storage. Must be "Debug" instead "Release". Verifiy it
..\ExtensibilityTest\bin\Debug\netcoreapp3.1\ExtensibilityTest.exe ..\ExtensibilityTest\bin\Debug\netcoreapp3.1\Extensions\netcoreapp3.1\MyExtension.dll
They are both in the same folder π€
Sorry, the problem is in Release mode, that points to Debug Folder
The new repo works in the same way that previous, with or without type definition
Hey @natemcmaster, I can't choose to remove AssemblyInfo.cs since it has InternalsVisibleTo
and XmlnsDefinition
attributes. Any help?
Hey @Teknel, I can't find a best example issue repro. Mine seems to be confusing. Can you provide a repro of your issue and I will update this issue to reflect yours too
Now working in a new approach to find the real problem of assembly loading. Talk to you in a while.
As our famous friend Jack said, go by peaces.
In out case. Eliminating types in sharedTypes resolves the SqlClient error, your big tip. Later we select the correct plugin comparing the class name reported by loader (who has all the classes existing in the assembly) with the desired class, and instantiate that.
Your case is different because in all the scenarios we test always works.
But something is wrong in the loader code because sharedTypes seems to be irrelevant in your case, and error prone in our.
Hope this info help to your problem. If not, we stay in contact to test your repos until find the solution.
No no... You got it wrong the SHARED TYPES are important and not sharing will cause a issue see What is a shared type. Loading assembly without passing shared types/assemblies may work in some cases but will cause bugs in many cases. There must some be some types/assemblies that have to be shared with plugins. Not passing types is pointless. I said it doesn't throw error if there are no shared types never said it will work fine. The problem is not with assembly loading but with dependency resolving of those plugins.
My host tries to load MyExtension.dll
which references *.Core.dll
and *.UI.dll
. So they also need to resolved, not from a file but from the host. The host also references those 2 DLLs. So the host must give them to plugin, thus the types will be shared. The problem is in the dependency resolving. You get it. It may seem to work, but will crash at some point
My approach of instantiating plugins may be different since I use an abstract class instead of an interface. But my problem I have to load the assembly and resolve it's dependencies at first.
Then I look through the types in those plugin and load the type that is a derivative of the base class.
I'm not saying I can't instantiate the types. My problem is can't even load them! That's my issue. Your approach is similar to mine, mine also works if I don't have sharedtypes which is risky. You're not seeing the real issue here. The process is : assembly load -> *resolve dependencies -> check the types -> load the instance of a type you want -> work with them
* The problem is here, SqlClient is referenced somehow and can't be resolved?. This is my issue. Other steps will work
Ok. Looking to the original problem. I remember that in the process of developing the MEF emulation we had the same problem. If we installed the SqlClient library then there was another required library and so on. What solved the problem was to load the environment libraries with *var runtimeAssemblies = Directory.GetFiles (RuntimeEnvironment.GetRuntimeDirectory (), " .dll");**
We have 2 levels, one with base implementation for all platforms and another, for example, for WPF.
At WPF level we have:
namespace TWPF.Core.Data.Plugins
{
/// <summary>
/// Clase para administracion de plugins wpf
/// </summary>
public class Manager
{
#region Metodos Publicos ------------------------------------------------------------------
/// <summary>Devuelve lista de plugins existentes en una carpeta base</summary>
/// <param name="folderPath"></param>
/// <param name="key"></param>
/// <returns></returns>
public static ObservableCollection<TKER.Core.Data.Plugins.Base> GetFromFolder(
string folderPath,
string key = "")
{
// Get the array of runtime assemblies.
var runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
// Create the list of assembly paths consisting of runtime assemblies and the inspected assembly.
var paths = new List<string>(runtimeAssemblies);
return TKER.Core.Data.Plugins.Manager.GetFromFolder(paths, folderPath, key);
}
#endregion
}
}
And at base level with NETCore
namespace TKER.Core.Data.Plugins
{
/// <summary>
/// Clase para administracion base de plugins
/// </summary>
public class Manager
{
#region Metodos Publicos ------------------------------------------------------------------
/// <summary>Devuelve lista de plugins existentes en una carpeta base</summary>
/// <param name="assyPaths"></param>
/// <param name="searchPath"></param>
/// <param name="key"></param>
/// <returns></returns>
public static ObservableCollection<Base> GetFromFolder(
List<string> assyPaths,
string searchPath,
string key = "")
{
var Plugins = new ObservableCollection<Base>();
var asm = typeof(Manager).Assembly;
assyPaths.Add(asm.Location);
// Busqueda de archivos en carpeta base ingresada .dll
var pluginFiles = Directory.GetFiles(searchPath, "*.dll", SearchOption.AllDirectories);
// Carga rutas de archivos .dll existentes
foreach (var pluginFile in pluginFiles)
{
assyPaths.Add(pluginFile);
}
// Create PathAssemblyResolver that can resolve assemblies using the created list.
var resolver = new PathAssemblyResolver(assyPaths);
using (var context = new MetadataLoadContext(resolver))
{
// Lazo para cada archivo dll encontrado
foreach (var pluginFile in pluginFiles)
{
var assembly = context.LoadFromAssemblyName(Path.GetFileNameWithoutExtension(pluginFile));
// Lazo para cada clase del assembly
foreach (var pluginType in assembly.GetTypes())
{
Global.Trace.Logger.DebugOutput(MethodBase.GetCurrentMethod(), "Plugin Found => " + pluginType.FullName);
var pluginData = new Base();
pluginData.AssemblyLocation = assembly.Location;
var attrCol = pluginType.GetCustomAttributesData();
var isAttrValid = false;
// Lazo para cada atributo existente en la clase seleccionada
foreach (var customAttributeData in attrCol)
{
if (customAttributeData.AttributeType.FullName == typeof(PluginExportAttribute).ToString())
{
isAttrValid = true;
for (var i = 0; i < customAttributeData.NamedArguments.Count; i++)
{
Global.Trace.Logger.DebugOutput(MethodBase.GetCurrentMethod(), "Arg " + i + " = " + customAttributeData.NamedArguments[i]);
var fieldName = customAttributeData.NamedArguments[i].ToString().GetBefore(" ");
foreach (var propertyInfo in pluginData.GetType().GetProperties())
{
if (propertyInfo.Name == fieldName)
{
switch (propertyInfo.PropertyType.Name)
{
case "String":
var dataString = customAttributeData.NamedArguments[i].ToString()
.GetAfter("= ");
propertyInfo.SetValue(pluginData, dataString);
break;
case "String[]":
var strComma = customAttributeData.NamedArguments[i].ToString()
.Replace(" ", string.Empty)
.GetAfter("{")
.GetBefore("}");
var array = strComma.Split(',');
propertyInfo.SetValue(pluginData, array);
break;
case "Guid":
var dataGuid = customAttributeData.NamedArguments[i].ToString()
.Replace(" ", string.Empty)
.GetAfter("=");
propertyInfo.SetValue(pluginData, new Guid(dataGuid));
break;
case "Boolean":
propertyInfo.SetValue(pluginData, customAttributeData.NamedArguments[i].ToString().Contains("True"));
break;
case "TKER.Core.Data.Version":
var dataVersion = new Version();
dataVersion.Parse(customAttributeData.NamedArguments[i].ToString());
propertyInfo.SetValue(pluginData, dataVersion);
break;
}
break;
}
}
}
}
}
if ((key == "" || pluginData.PluginType == key) && isAttrValid)
{
Plugins.Add(pluginData);
}
}
}
}
return Plugins;
}
#endregion
}
}
We are going to test again this approach to see if loading SqlClient may be resolved, because in first attempts was not successful.
Take a look to this routines, because may be useful to you to get metadata of plugins without loading assemblies. Ask me if you need explanation about the code.
We stay in contact
But for creating an instance you still need to load assemblies and resolve their deps
Yes.
this is where we make the instance of loaded plugin.
protected async void SolutionCreateConfirmAsync()
{
StringBuilder errors = new StringBuilder();
#region Test items completos.
foreach (var solutionProject in this.SolutionProjects)
{
if (solutionProject.IsSelected == true)
{
if (string.IsNullOrEmpty(solutionProject.Name))
{
errors.AppendLine("No Name in " + solutionProject.Title);
}
}
}
if (string.IsNullOrEmpty(this.NewSolutionName))
{
errors.AppendLine("Empty Solution Name");
}
if ((this.IsStorageCustom) && (string.IsNullOrEmpty(this.NewSolutionFolder)))
{
errors.AppendLine("Empty Solution Folder");
}
if (errors.Length > 0)
{
await Manager.ShowLocalMessage(
"Error en Configuracion de Solucion Nueva",
"Core_States_Error",
"La configuracion de la solucion nueva tiene errores.",
"Verifique los siguientes elementos faltantes",
errors.ToString(),
GlobalData.SysButtonId.Ok);
return;
}
#endregion
#region Solution Create
try
{
var loader = PluginLoader.CreateFromAssemblyFile(
this.SolutionTemplateSelected.AssemblyLocation,
isUnloadable: true,
sharedTypes: new Type[]
{
//typeof(TekStudio.Core.Modules.Solutions.IBase)
}
);
foreach (var pluginType in loader
.LoadDefaultAssembly()
.GetTypes()
.Where(t => t.Name == this.SolutionTemplateSelected.ClassName))
{
TekStudio.Core.Modules.Solutions.Base solution = (TekStudio.Core.Modules.Solutions.Base)Activator.CreateInstance(pluginType);
// Carga datos de la metadata del plugin a la clase instanciada
solution.ViewModel.Model.Config.Plugin = this.SolutionTemplateSelected;
solution.ViewModel.Model.Config.Name = this.NewSolutionName;
solution.ViewModel.Model.Config.StorageRootPath = this.NewSolutionFolder;
solution.ViewModel.Model.Config.DateTimeCreated = DateTime.Now;
solution.ViewModel.Model.Config.Version = new Version(1, 0, 0, 0);
solution.Title=this.NewSolutionName;
TsGlobal.App.ShellViewModel.DockApps.Add(solution);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
#endregion
}
In Solution Create region
The real problem will be seen if you do this
This is right
var loader = PluginLoader.CreateFromAssemblyFile(
this.SolutionTemplateSelected.AssemblyLocation,
isUnloadable: true,
sharedTypes: new Type[]
{
typeof(TekStudio.Core.Modules.Solutions.IBase)
});
instead of this
var loader = PluginLoader.CreateFromAssemblyFile(
this.SolutionTemplateSelected.AssemblyLocation,
isUnloadable: true,
sharedTypes: new Type[]
{
//typeof(TekStudio.Core.Modules.Solutions.IBase)
});
And this is wrong
Ok from what I understood:
MetadataLoadContext
to load assemblies and PathAssemblyResolver
to resolve their depsMetadataLoadContext
MetadataLoadContext
this McMaster library already can do the job of MetadataLoadContext
and PathAssemblyResolver
combined.var assembly = context.LoadFromAssemblyName(Path.GetFileNameWithoutExtension(pluginFile));
to get the assembly. I use loader.LoadDefaultAssembly()
. Basically the same.MetadataLoadContext
to verify if it's a plugin and this library to load them.You're manually doing things that this library can already do. That's why I'm using this library
You are not passing any shared type? read my comment
The functionality of the #first few functions is just to take the metadata info from the assemblies without loading them, which was a great MEF function. In our project, the number of available plugins can be high, so we cannot load them all. When consulted with McMaster, he said that this was not implemented and that it should be resolved outside the current library. That is the reason why we do it manually without using the McMaster library. Then we use the McMaster library to load the selected plugin, since it should solve the loading problems of the assemblies required by the plugin.
Your comment about shared types is noted and we are looking about.
So you're just getting metadata from *.dll files and store those metadata in a list -> use those metadatas to verify plugins -> load plugin using this library.
I used this library for all of them π
. But we will have the same problem if there are sharedTypes
, don't we?
Exactly. We have the same problem. The difference in our projects is that you load all plugins assemblies and we don't.
So the real problem is hitting when we use this library and try to load a library which is WPF library.
The problem must be with the either ManagedLoadContext or AssemblyLoadContext inside this library.
Your first approach works because MetadataLoadContext
is different from AssemblyLoadContext
But... Why your repo works in our machine? And plugins seems to be loaded and instantiated correctly.
But... Why your repo works in our machine? And plugins seems to be loaded and instantiated correctly.
That's what I thinking. Honestly I don't why it happens to work for you. That's why I said
Hey @Teknel, I can't find a best example issue repro. Mine seems to be confusing. Can you provide a repro of your issue and I will update this issue to reflect yours too
Looks that we must to focus more on environment than in the library for your case. But VS and NETCore seems to be the same.
Another info reported by System Information: System Information report written at: 06/19/20 09:17:24 System Name: TEK-MASTER [System Summary]
Item Value
OS Name Microsoft Windows 10 Pro
Version 10.0.19041 Build 19041
Other OS Description Not Available
OS Manufacturer Microsoft Corporation
System Name TEK-MASTER
System Manufacturer Gigabyte Technology Co., Ltd.
System Model Z390 GAMING X
System Type x64-based PC
System SKU Default string
Processor Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz, 3600 Mhz, 8 Core(s), 16 Logical Processor(s)
BIOS Version/Date American Megatrends Inc. F6, 12/4/2018
SMBIOS Version 3.1
Embedded Controller Version 255.255
BIOS Mode UEFI
BaseBoard Manufacturer Gigabyte Technology Co., Ltd.
BaseBoard Product Z390 GAMING X-CF
BaseBoard Version Default string
Platform Role Desktop
Secure Boot State Off
PCR7 Configuration Binding Not Possible
Windows Directory C:\WINDOWS
System Directory C:\WINDOWS\system32
Boot Device \Device\HarddiskVolume7
Locale United States
Hardware Abstraction Layer Version = "10.0.19041.1"
User Name TEK-MASTER\tek-m
Time Zone Argentina Standard Time
Installed Physical Memory (RAM) 64.0 GB
Total Physical Memory 63.9 GB
Available Physical Memory 34.8 GB
Total Virtual Memory 63.9 GB
Available Virtual Memory 28.6 GB
Page File Space 0 bytes
Kernel DMA Protection Off
Virtualization-based security Not enabled
Device Encryption Support Reasons for failed automatic device encryption: TPM is not usable, PCR7 binding is not supported, Hardware Security Test Interface failed and device is not Modern Standby, Un-allowed DMA capable bus/device(s) detected, TPM is not usable
Hyper-V - VM Monitor Mode Extensions Yes
Hyper-V - Second Level Address Translation Extensions Yes
Hyper-V - Virtualization Enabled in Firmware Yes
Hyper-V - Data Execution Protection Yes
What I can offer you is a TeamViewer session so you can use our environment with your solution
I'm on a limited data plan, I can't use TeamViewer π but thanks for your offering. I very happy you're helping me with this issue β€.
What I can do is to test your solution in other of our machines. I wil do and tell you soon.
Thanks a lot @Teknel. I'm very lucky to have your help
Same result. Repo works fine. This is the output info:
'ExtensibilityTest.exe' (CoreCLR: DefaultDomain): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Private.CoreLib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\ExtensibilityTest.dll'. Symbols loaded. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\PresentationFramework.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\WindowsBase.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\System.Xaml.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. Step into: Stepping over non-user code 'ExtensibilityTest.App.Main' Step into: Stepping over non-user code 'ExtensibilityTest.App..ctor' 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\System.IO.Packaging.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\netstandard.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Private.Uri.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\PresentationCore.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\mscorlib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\DirectWriteForwarder.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.InteropServices.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.CompilerServices.VisualC.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Diagnostics.Debug.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Threading.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\Microsoft.Win32.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Collections.NonGeneric.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Linq.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Collections.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\Microsoft.Win32.Registry.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Diagnostics.TraceSource.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Collections.Specialized.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.ComponentModel.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Diagnostics.Process.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Threading.Thread.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\System.Configuration.ConfigurationManager.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Xml.ReaderWriter.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Private.Xml.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.IO.FileSystem.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Net.WebClient.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Memory.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Security.Cryptography.Algorithms.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Text.Encoding.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Threading.Tasks.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. Step into: Stepping over non-user code 'ExtensibilityTest.App.InitializeComponent' 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.ComponentModel.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Resources.ResourceManager.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.ComponentModel.TypeConverter.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\System.Windows.Extensions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Threading.ThreadPool.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Collections.Concurrent.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.ObjectModel.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\UIAutomationTypes.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\PresentationFramework.Aero2.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Drawing.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\PresentationFramework-SystemXml.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'c:\program files (x86)\microsoft visual studio\2019\preview\common7\ide\commonextensions\microsoft\xamldiagnostics\Core\x64\Microsoft.VisualStudio.DesignTools.WpfTap.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Diagnostics.Tracing.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Text.RegularExpressions.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.IO.Pipes.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Console.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Threading.Timer.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.Serialization.Xml.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Private.DataContractSerialization.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.Serialization.Json.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.Serialization.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Reflection.Emit.ILGeneration.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Reflection.Emit.Lightweight.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Reflection.Primitives.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Buffers.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.Serialization.Formatters.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\UIAutomationProvider.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\3.1.4\System.Windows.Controls.Ribbon.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\McMaster.NETCore.Plugins.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\ExtensibilityTest.Core.dll'. Symbols loaded. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\ExtensibilityTest.UI.dll'. Symbols loaded. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.Loader.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\Extensions\netcoreapp3.1\MyExtension.dll'. Symbols loaded. My Extension, A test extension to check extensibility 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\Extensions\netcoreapp3.1\MyExtension.dll'. Symbols loaded. My Extension, A test extension to check extensibility 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\Extensions\netcoreapp3.1\MyExtension.dll'. Symbols loaded. My Extension, A test extension to check extensibility
for each button pressed
'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\McMaster.NETCore.Plugins.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\ExtensibilityTest.Core.dll'. Symbols loaded. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\ExtensibilityTest.UI.dll'. Symbols loaded. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.4\System.Runtime.Loader.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'ExtensibilityTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\Tek-r\Documents\ExtensibilityTest-main\ExtensibilityTest-main\ExtensibilityTest\bin\Debug\netcoreapp3.1\Extensions\netcoreapp3.1\MyExtension.dll'. Symbols loaded. My Extension, A test extension to check extensibility
It getting too confusing π
Describe the bug I'm creating an application which will load plugins from a directory (.\Extensions) in .NET Core 3.1 that's why I chose this library. Previously (in .NET 4.6.2) I was using AppDomain.AssemblyResolve to resolve dependencies and share some assemblies with the plugins. More details below.
My project structure is basically this :
The plugins will reference the core library and the UI library (in some cases). The main host app will resolve dependencies of the plugins using AppDomain.AssemblyResolve and share the core logic and UI libs with them.
This method still works. But I want features of this library such Unloading, HotReload, etc. So I switched to use this library and changed the code correspondingly.
But the problem is all 3 libraries are WPF .NET Core 3.1 libraries
The Core logic library depends on System.Drawing and the UI library depends on a 3rd party library (ModernWpf)
So to overcome the isolation boundry I have to share the types common to them like this :
I expected it to work like in .NET 4.6.2 (using AppDomain.AssemblyResolve) but it doesn't. It throws this System.IO.FileNotFoundException saying
To Reproduce Steps to reproduce the behavior: I'm on a tight schedule and I can't provide any repro of it but basically
Expected behavior I don't have any dependencies to System.Data.SqlClient. I want mine to work like it did in .NET 4.6.2
Screenshots
Additional context I even tried to remove the .Core and .UI references from the plugin and modified the loading as
The plugin is basically just an empty dll but it still throws the same error.
It only works if there are no shared types (But what's the point of plugin then?) like this:
The architecture of my project :