簡體   English   中英

ASP.Net核心MVC依賴注入不起作用

[英]ASP.Net Core MVC Dependency Injection not working

我試圖將一個接口注入我的HomeController,我收到此錯誤:

InvalidOperationException:嘗試激活時無法解析類型為“Microsoft.Extensions.Configuration.IConfiguration”的服務

我的Startup類如下:

public Startup(IApplicationEnvironment appEnv)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(appEnv.ApplicationBasePath)
        .AddEnvironmentVariables()
        .AddJsonFile("appsettings.json");
    Configuration = builder.Build();
}

public IConfigurationRoot Configuration { get; set; }

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddApplicationInsightsTelemetry(Configuration);

    services.AddEntityFramework()
        .AddSqlServer()
        .AddDbContext<ApplicationDbContext>(options => options
            .UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));

    services.AddIdentity<ApplicationUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>()
        .AddDefaultTokenProviders();

    services.AddMvc();
    services.AddSingleton(provider => Configuration);

    // Add application services.
    services.AddTransient<IEmailSender, AuthMessageSender>();
    services.AddTransient<ISmsSender, AuthMessageSender>();
}

public void Configure(
    IApplicationBuilder app, 
    IHostingEnvironment env, 
    ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    app.UseApplicationInsightsRequestTelemetry();

    if (env.IsDevelopment())
    {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");

        try
        {
            using (var serviceScope = app.ApplicationServices
                .GetRequiredService<IServiceScopeFactory>()
                .CreateScope())
            {
                serviceScope.ServiceProvider
                        .GetService<ApplicationDbContext>()
                        .Database.Migrate();
            }
        }
        catch { }
    }

    app.UseIISPlatformHandler(options => options.AuthenticationDescriptions.Clear());

    app.UseApplicationInsightsExceptionTelemetry();
    app.UseStaticFiles();
    app.UseIdentity();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });

    app.Run((async (context) =>
    {
        await context.Response.WriteAsync("Error");
    }));
}

我的HomeController構造函數是:

public HomeController(IConfiguration configuration, IEmailSender mailService)
{
    _mailService = mailService;
    _to = configuration["emailAddress.Support"];
}

請告訴我哪里弄錯了。

Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider提供程序,ISet`1 callSiteChain,ParameterInfo []參數,Boolean throwIfCallSiteNotFound)

嘗試將其作為IConfigurationRoot而不是IConfiguration注入:

 public HomeController(IConfigurationRoot configuration
    , IEmailSender mailService)
{
    _mailService = mailService;
    _to = configuration["emailAddress.Support"];
}

在這種情況下,行

services.AddSingleton(provider => Configuration);

相當於

services.AddSingleton<IConfigurationRoot>(provider => Configuration);

因為類的Configuration屬性是這樣聲明的,並且注入將通過匹配它注冊的任何類型來完成。 我們可以很容易地復制它,這可能會更清楚:

public interface IParent { }

public interface IChild : IParent { }

public class ConfigurationTester : IChild { }
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    IChild example = new ConfigurationTester();
    services.AddSingleton(provider => example);
}
public class HomeController : Controller
{
    public HomeController(IParent configuration)
    {
        // this will blow up
    }
}

然而

正如評論中提到的stephen.vakil一樣,最好將配置文件加載到類中,然后根據需要將該類注入控制器。 這看起來像這樣:

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

您可以使用IOptions接口獲取這些配置:

public HomeController(IOptions<AppSettings> appSettings)

在Core 2.0中,建議使用IConfiguration而不是IConfigurationRoot

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public IConfiguration Configuration { get; }

來自https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/#add-configuration-providers

將項目從.Net Core 1.x移動到2.0時,將所有IConfigurationRoot更改為IConfiguration

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM