1

我是ASP.NET Core MVC的新手,並且遇到依賴注入的問題。ASP.NET Core MVC依賴注入問題

我有一個解決方案,我想共享一個EF數據庫上下文類的多個項目。我爲配置管理器定義了一個接口,這樣我就可以跨項目共享通用配置,但也具有項目特定的配置。

運行時的各種API的依賴注入失敗,並

"System.InvalidOperationException: Unable to resolve service for type IConfigManager"

錯誤。

Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddl‌​eware[0] An unhandled exception has occurred while executing the request System.InvalidOperationException: Unable to resolve service for type 'NovaSec.Core.IConfigManager' while attempting to activate 'NovaSec.Core.Contexts.CustomDbContext'. at Microsoft.Extensions.DependencyInjection.ServiceLookup.Servi‌​ce.PopulateCallSites‌​(ServiceProvider provider, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)

DBContextClass是我在其他項目中引用的類庫項目的一部分。

我不知道爲什麼它不起作用。有人可以幫助並向我解釋這個嗎?

的DbContext類

public class CustomDbContext : IdentityDbContext<CustomIdentity, CustomRole, string> 
    { 
     public CustomDbContext(DbContextOptions<CustomDbContext> options, IConfigManager configManager) : base(options) 
     { 
      var optionsBuilder = new DbContextOptionsBuilder<CustomDbContext>(); 
      optionsBuilder.UseSqlite(configManager._config.ConnectionStrings.FirstOrDefault(c => c.id == "IdentityDatabase").connectionString); 
     } 
    } 

配置管理器接口和實現類

public interface IConfigManager 
{ 
    IAppConfig _config { get; set; } 
} 

public class ConfigManager : IConfigManager 
{ 
    public IAppConfig _config { get; set; } 
    public ConfigManager(IAppConfig config) 
    { 

    } 
} 

啓動方法

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddSingleton<IConfigManager, ConfigManager>(config => 
    { 
     return new ConfigManager(_config); 
    }); 
    IServiceProvider serviceProvider = services.BuildServiceProvider(); 
    _configManager = (ConfigManager)serviceProvider.GetService<IConfigManager>(); 
    services.AddDbContext<CustomDbContext>(); 
    services.AddIdentity<CustomIdentity, CustomRole>(config => { 
     config.SignIn.RequireConfirmedEmail = true; 
    }) 
     .AddEntityFrameworkStores<CustomDbContext>() 
     .AddDefaultTokenProviders(); 
    services.AddIdentityServer() 
    .AddInMemoryClients(_configManager.GetClients()) 
    .AddInMemoryIdentityResources(_configManager.GetIdentityResources()) 
    .AddInMemoryApiResources(_configManager.GetApiResources()) 
    .AddTemporarySigningCredential() 
    .AddAspNetIdentity<CustomIdentity>(); 

} 
+0

難道連合mpile?提供可用於重現問題的[mcve]。 – Nkosi

+0

您不要在配置方法內部構建服務提供者,並且在構建提供者後不添加服務。 –

回答

0

好吧,我終於明白了。最終的結果是:

的DbContext類

public class CustomDbContext : IdentityDbContext<CustomIdentity, CustomRole, string> 
{ 
    private readonly IConfigManager _configManager; 
    public CustomDbContext(DbContextOptions<CustomDbContext> options, IConfigManager configManager) : base(options) 
    { 
     this._configManager = configManager; 
    } 

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 
    { 
     optionsBuilder.UseSqlite(_configManager._config.ConnectionStrings.FirstOrDefault(c => c.id == "IdentityDatabase").connectionString); 
    } 
} 

啓動

public IConfigurationRoot Configuration { get; set; } 
public ConfigManager ConfigManager { get; set; } 
public AppConfig Config { get; set; } 
// This method gets called by the runtime. Use this method to add services to the container. 
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 
public Startup(IHostingEnvironment env) 
{ 
    var builder = new ConfigurationBuilder() 
    .SetBasePath(Directory.GetCurrentDirectory()) 
    .AddJsonFile("appsettings.json") 
    .AddEnvironmentVariables(); 

    this.Configuration = builder.Build(); 
    this.Config = new AppConfig(); 
    this.Configuration.Bind(this.Config); 
    this.ConfigManager = new ConfigManager(this.Config); 
} 

public void ConfigureServices(IServiceCollection services) 
{ 
    services.AddSingleton<IConfigManager, ConfigManager>(provider => this.ConfigManager); 
    services.AddDbContext<CustomDbContext>(); 
    services.AddIdentity<CustomIdentity, CustomRole>(config => { 
     config.SignIn.RequireConfirmedEmail = true; 
    }) 
     .AddEntityFrameworkStores<CustomDbContext>() 
     .AddDefaultTokenProviders(); 
    services.AddIdentityServer() 
    .AddInMemoryClients(this.ConfigManager.GetClients()) 
    .AddInMemoryIdentityResources(this.ConfigManager.GetIdentityResources()) 
    .AddInMemoryApiResources(this.ConfigManager.GetApiResources()) 
    .AddTemporarySigningCredential() 
    .AddAspNetIdentity<CustomIdentity>(); 
} 

CONFIGMANAGER

public interface IConfigManager 
{ 
    IAppConfig _config { get; set; } 
} 

public class ConfigManager : IConfigManager 
    { 
     public IAppConfig _config { get; set; } 
     public ConfigManager(IAppConfig config) 
     { 
      this._config = config; 
     } 

    } 
} 
2

在這個階段,您最好手動創建管理器,將其用於配置,然後將其註冊到服務集合中。

更新方面

public class CustomDbContext : IdentityDbContext<CustomIdentity, CustomRole, string> { 
    public CustomDbContext(DbContextOptions<CustomDbContext> options) : base(options) { } 
} 

您還應該配置在啓動的上下文。

public void ConfigureServices(IServiceCollection services) { 
    var _configManager = new ConfigManager(_config); //Create new instance 
    services.AddSingleton<IConfigManager>(provider => _configManager); // add as singleton 

    services.AddDbContext<CustomDbContext>(options => 
     options.UseSqlite(_configManager._config.ConnectionStrings.FirstOrDefault(c => c.id == "IdentityDatabase").connectionString) 
    ); 

    services.AddIdentity<CustomIdentity, CustomRole>(config => { 
     config.SignIn.RequireConfirmedEmail = true; 
    }) 
     .AddEntityFrameworkStores<CustomDbContext>() 
     .AddDefaultTokenProviders(); 

    services.AddIdentityServer() 
     .AddInMemoryClients(_configManager.GetClients()) 
     .AddInMemoryIdentityResources(_configManager.GetIdentityResources()) 
     .AddInMemoryApiResources(_configManager.GetApiResources()) 
     .AddTemporarySigningCredential() 
     .AddAspNetIdentity<CustomIdentity>(); 

} 
+0

謝謝!我也嘗試過。它引發相同的錯誤:失敗:Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware [0] 執行請求時發生未處理的異常 System.InvalidOperationException:嘗試激活時無法解析類型爲「NovaSec.Core.IConfigManager」的服務'NovaSec.Core.Contexts.CustomDbContext'。 at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider,ISet'1 callSiteChain,ParameterInfo [] parameters,Boolean throwIfCallSiteNotFound) –

+0

此錯誤被拋出的位置 – Nkosi

+0

當我在我的應用程序上調用任何控制器時。如果我直接在配置服務中配置DBContextClass,如 services.AddDbContext (options => options.UseSqlite(「Data Source = idenitysource.db」)) 它一切正常。它似乎與不接收configManager對象的CustomDbContext類構造函數有關。 –