ASP.Net Core MVC 依赖注入不起作用
Posted
技术标签:
【中文标题】ASP.Net Core MVC 依赖注入不起作用【英文标题】:ASP.Net Core MVC Dependency Injection not working 【发布时间】:2016-04-22 19:24:43 【问题描述】:我正在尝试将接口注入到我的 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 provider, ISet`1 callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
【问题讨论】:
我建议您通过创建一个 POCO 来存储您想要传递的任何配置详细信息并将其注入,从而将您的Configuration
与您的 Controller
隔离开来。
如果构造函数有对象作为参数,但服务配置为接口***.com/questions/40900414/…,也会发生类似的错误
【参考方案1】:
尝试将其注入为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
然而
正如 cmets 中提到的 stephen.vakil,最好将配置文件加载到一个类中,然后根据需要将该类注入到控制器中。看起来像这样:
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
您可以通过IOptions
接口获取这些配置:
public HomeController(IOptions<AppSettings> appSettings)
【讨论】:
为什么?我没有在我的代码中这样做,它仍然可以正常工作。并且在文档中没有按此顺序完成:docs.asp.net/en/latest/fundamentals/dependency-injection.html @stephen.vakil 你是对的,我在那个细节上完全错了。感谢您的链接! Jam,我已经更新了我的答案。 就是这样!你能解释一下有什么区别吗? 将其作为IConfiguration
注入以获得更大的灵活性。【参考方案2】:
在 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
【讨论】:
【参考方案3】:将项目从 .Net Core 1.x 移动到 2.0 时,将所有 IConfigurationRoot
更改为 IConfiguration
【讨论】:
以上是关于ASP.Net Core MVC 依赖注入不起作用的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core MVC 之依赖注入 Controller
ASP.NET Core Web 应用程序系列- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)
如何在 ASP.NET Core MVC 中使用依赖注入设计存储库模式?
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)
ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)