ASP.Net Core MVC依赖项注入不起作用 [英] ASP.Net Core MVC Dependency Injection not working

查看:170
本文介绍了ASP.Net Core MVC依赖项注入不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将接口插入到HomeController中,并且出现此错误:

I am trying to inject a interface into to my HomeController and I am getting this error:

InvalidOperationException:尝试激活

InvalidOperationException: Unable to resolve service for type 'Microsoft.Extensions.Configuration.IConfiguration' while attempting to activate

我的启动类如下:

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构造函数是:

and my HomeController constructor is:

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

请告诉我我在哪里弄错了.

Please tell me where I am mistaken.

Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider,ISet`1 callSiteChain,ParameterInfo []参数,布尔throwIfCallSiteNotFound)

Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)

推荐答案

尝试将其作为IConfigurationRoot而不是IConfiguration注入:

Try injecting it as an IConfigurationRoot instead of IConfiguration:

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

在这种情况下,该行

services.AddSingleton(provider => Configuration);

等效于

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

因为类上的Configuration属性是这样声明的,所以注入将通过匹配它注册为的任何类型来完成.我们可以很容易地复制它,这可能使它更清晰:

because the Configuration property on the class is declared as such, and injection will be done by matching whatever type it was registered as. We can replicate this pretty easily, which might make it clearer:

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一样,最好将配置文件加载到一个类中,然后根据需要将该类注入到控制器中.看起来像这样:

However

As stephen.vakil mentioned in the comments, it would be better to load your configuration file into a class, and then inject that class into controllers as needed. That would look something like this:

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

您可以使用IOptions界面获取以下配置:

You can grab these configurations with the IOptions interface:

public HomeController(IOptions<AppSettings> appSettings)

这篇关于ASP.Net Core MVC依赖项注入不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆