public static ApplicationPartManager AddModularApplicationPart(this IServiceCollection services, string moduleDir) { var env = GetServiceFromCollection <IWebHostEnvironment>(services); var moduleFileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, moduleDir)); services.AddTransient <IConfigureOptions <ModuleMvcOptions>, ModuleMvcOptionsSetup>(); services.PostConfigure <ModuleMvcOptions>(options => { options.FileProviders.Clear(); options.FileProviders.Add(moduleFileProvider); }); services.AddSingleton <ModuleMvcFileProvider>(); services.AddSingleton <IModuleChangeProvider, CompositeModuleChangeProvider>(); services.AddSingleton <IActionDescriptorChangeProvider, ModuleActionDescriptorChangeProvider>(); var compilerProvider = services.FirstOrDefault(f => f.ServiceType == typeof(IViewCompilerProvider) && f.ImplementationType?.Assembly == typeof(IViewCompilerProvider).Assembly && f.ImplementationType.FullName == "Microsoft.AspNetCore.Mvc.Razor.Compilation.DefaultViewCompilerProvider"); if (compilerProvider != null) { // Replace the default implementation of IViewCompilerProvider services.Remove(compilerProvider); } services.TryAddSingleton <IViewCompilerProvider, ModuleViewCompilerProvider>(); ApplicationPartManager applicationPartManager = GetServiceFromCollection <ApplicationPartManager>(services); if (applicationPartManager == null) { throw new ArgumentNullException(nameof(applicationPartManager)); } applicationPartManager.PopulateModuleParts(GetControllerModules(moduleFileProvider)); // DI of the module project can't unload //var moduleAssemblyParts = applicationPartManager.ApplicationParts.OfType<ControllerModulesAssemblyPart>().ToList(); //foreach (var moduleAssemblyPart in moduleAssemblyParts) //{ // foreach (var attribute in moduleAssemblyPart.Assembly.GetCustomAttributes<HostingServiceStartupAttribute>()) // { // var hostingStartup = (IHostingServiceStartup)Activator.CreateInstance(attribute.HostingStartupType); // hostingStartup.Configure(services); // } //} return(applicationPartManager); }