Home > database >  .net6 IServiceProvider service registered in runtime loaded assembly not resolved by main assembly (
.net6 IServiceProvider service registered in runtime loaded assembly not resolved by main assembly (

Time:11-30

The project I'm working on has multiple DDL's loaded at runtime, with common interfaces to pass the main IServiceCollection to register custom services. The following was working in TFM net461 and no longer works after migrating to net6.

Project structure:

  • Main assembly: .net core web app MVC
  • Side assemblies: .net core sdk ddl (application parts)

The main problem being the DbContext service, registered in Startup.ConfigureServices by calling the common interface method and passing in the main assembly IServiceCollection:

services.AddDbContext<DatabaseContext>(options => {
                if (!options.IsConfigured) options.UseSqlServer(Configuration.GetConnectionString(connectionString));
            });

After all the runtime registrations take place, I can successfully see the service registered in the collection in the main assembly (by debugging internal properties). However, in Startup.Configure with the injected IServiceProvider I'm not able to find the previously registered service DatabaseContext if the code is executing in a different assembly than the one in which it was registered. While it gets correctly resolved within the same runtime assembly where the service was added in the first place.

I tried:

  • Checking all of the project's dependencies to make sure the versions are correct;
  • Creating a scope with IApplicationBuilder.ApplicationServices.CreateScope() and using the IServiceProvider of the scope; -- same result

I'm expecting the service to be found by all executing assemblies (main and dynamically loaded ones) like it was when executing within .NET Framework with TFM net461. It seems as if every loaded assembly has its own IServiceCollection only when executing IServiceProvider.GetService, even if every assembly its using the same instance of IServiceProvider provided by the main executing assembly (the one with the startup).

CodePudding user response:

What seemed to cause the described issue was how I was loading the external assemblies.
Previously in net461 the following procedure was working:

Assembly.LoadFile(dll)

Indeed allowing by reflection to instantiate the types that implement the custom interfaces, and all the code had the same 'execution context'.
Thus allowing other assemblies (e.g. the main assembly, but also other side-assemblies) to correctly obtain the registered services.

After some research and other tries, I came upon the following docs: About AssemblyLoadContext
The main principle was about the shared depencencies section, so I tried to replace the previous line with:

AssemblyLoadContext.Default.LoadFromAssemblyPath(dll)

With this change, finally the behaviour was the same as before upgrading to net6.

  • Related