-
-
Notifications
You must be signed in to change notification settings - Fork 241
Description
Please find the following example. I was struggling with type registration in DI container and then using service provider to create these types. The error I was getting was that certain type was not registered. I figured out that types should be registered and retrieved using in the same AssemblyLoadContext.
My question is how assembly load contexts are identified and what is the correct way of DI type registration.
In the following example a plugin is loaded using loader created by PluginLoader.CreateFromAssemblyFile(pluginPath).
After building the provider and constructing the scope, if i use the same loader the type is retrieved correctly but if I create another loader from the same assembly path and enter its context then the type is not found in the container.
[TestMethod]
public void TestServiceProvider()
{
string assemblyName = "MyPluginAssembly";
string className = "MyPluginAssembly.MyClass";
string typeName = $"{className}, {assemblyName}";
string pluginPath = "c:\\plugins\\MyPluginAssembly.dll";
var services = new ServiceCollection();
var loader1 = PluginLoader.CreateFromAssemblyFile(pluginPath);
using (loader1.EnterContextualReflection())
{
Type t1 = Type.GetType(typeName);
Assert.IsNotNull(t1);
var alc1 = AssemblyLoadContext.GetLoadContext(t1.Assembly);
services.TryAddTransient(t1);
}
var serviceProvider = services.BuildServiceProvider();
var scope = serviceProvider.CreateScope();
using (loader1.EnterContextualReflection())
{
Type t2 = Type.GetType(typeName);
Assert.IsNotNull(t2);
var alc2 = AssemblyLoadContext.GetLoadContext(t2.Assembly);
var i2 = scope.ServiceProvider.GetService(t2); //i2 is OK
Assert.IsNotNull(i2);
}
var loader2 = PluginLoader.CreateFromAssemblyFile(pluginPath);
using (loader2.EnterContextualReflection())
{
Type t3 = Type.GetType(typeName);
Assert.IsNotNull(t3);
var alc2 = AssemblyLoadContext.GetLoadContext(t3.Assembly);
var i3 = scope.ServiceProvider.GetService(t3); //i3 is null
Assert.IsNotNull(i3);
}
}