-
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
IConfiguration not resolving inside plugins #111022
Comments
I think the problem is that the plugin has its own copy of the Microsoft.Extensions.Configuration.Abstractions assembly, and PluginLoadContext resolves to that, so there are two copies of the IConfiguration type. Does it work if you change the package references in HelloPlugin to these (i.e. use the *.Abstractions packages and exclude runtime assets): <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="9.0.0">
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.0">
<ExcludeAssets>runtime</ExcludeAssets>
</PackageReference>
</ItemGroup> Alternatively, I guess you could change PluginLoadContext to force the plugin to use the application's copies of those assemblies; but it seems better to exclude the assets so that they are not unnecessarily deployed with the plugin. |
I didn't find the "cannot be called in this context" message anywhere in the .NET Runtime source code. |
Awesome, this fixed it. This seems to be explained in the docs somehow, but was confused as the serviceType still showed as registered with the serviceProvider. Didnt think about having it twice and then not receiving any. |
Perhaps the DI container implementation could be changed so that, if it is going to throw an exception because a service is required but has not been registered, then it would check if a service has been registered for an identically-named but distinct type, and change Exception.Message to mention that as a probable reason of the error. |
If I understand you correctly this would be a reasonable solution. So the current problem was that there were two IConfiguration types which are of different types because they were loaded from different assemblies (the plugin and the project one). So with your solution the plugin developer, would get a warning that there is an identical type registered and probably point to the suggested solution in the docs to exclude the assets at runtime? |
It could be part of ServiceProviderOptions.ValidateOnBuild too. If validation fails, then BuildServiceProvider compare the type names in order to detect whether an assembly loading problem is the cause. So the developer would get a better error message in the "development" environment where this validation is enabled by default. If implemented that way, I hope the extra checks would not hurt performance in production environments. |
In your plugin scenario, it might be best to make the PluginBase project reference the Microsoft.Extensions.Configuration.Abstractions package and let HelloPlugin get the reference from there. If plugins require IConfiguration to be available for injection into their constructors, then that is part of the plugin contract even if PluginBase.ICommand does not reference IConfiguration. If the set of assemblies that the host provides to plugins changes over time, then it is nicer to define it centrally in PluginBase than separately in each plugin. |
Description
If I try to resolve the IConfiguration inside a loaded plugin, the serviceProvider fails to resolve the instance, even if it is listed with its resolve-function inside the service descriptors.
I basically followed this tutorial: https://learn.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support
Changed the console app to use GenericHost to enable DI and Configuration usage.
And tried to access the IConfiguration instance inside the plugin.
Relevant output from StackTrace: Method System.Reflection.MemberInfo.get_CustomAttributes cannot be called in this context
AdditionalInfo:
IConfiguration is listed in the ServiceDescriptors with
I also can not create a Scope from the injected ServiceProvider.
Reproduction Steps
Expected behavior
IConfiguration should be resolved inside the plugin just like the service provider.
Actual behavior
Regression?
No response
Known Workarounds
No response
Configuration
.NET 9
Windows 11
x64
Other information
No response
The text was updated successfully, but these errors were encountered: