C# .Net Web Api 2.2终结点中的依赖项注入不可用
我有一个控制台应用程序,它的工作原理类似于web api。 我在Program.cs注册C# .Net Web Api 2.2终结点中的依赖项注入不可用,c#,asp.net-web-api,dependency-injection,.net-core,C#,Asp.net Web Api,Dependency Injection,.net Core,我有一个控制台应用程序,它的工作原理类似于web api。 我在Program.cs注册 var collection = new ServiceCollection(); collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>(); 为什么构造函数没有得到依赖注入,或者为什么构造函数没有被调用? public class Program { #region fields and propetr
var collection = new ServiceCollection();
collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>();
为什么构造函数没有得到依赖注入,或者为什么构造函数没有被调用?
public class Program
{
#region fields and propetries
public IConfiguration Configuration { get; }
//# if DEBUG
//#endif
public static IConnection Connection { get; set; }
public static ITimeSeriesBusinessComponent TimeSeriesBusinessComponent { get; set; }
public static IInfoBusinessComponent InfoBusinessComponent { get; set; }
private static int counter;
#endregion fields and propetries
public static void Main(string[] args)
{
IConfiguration config = GetConfigurations();
ILogger logger = GetLogger();
ServiceProvider appServiceProvider = GetServiceProvider(config);
Parallel.Invoke
(
() =>
{
BuildWebHost(args).Build().Run();
},
() =>
{
//...
}
);
}
private static IConfiguration GetConfigurations()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
return config;
}
private static ILogger GetLogger()
{
ILogger logger = new LoggerFactory().AddNLog().CreateLogger<Program>();
return logger;
}
private static ServiceProvider GetServiceProvider(IConfiguration config)
{
var collection = new ServiceCollection();
collection.AddLogging(configuration => configuration.AddNLog());
//...
collection.AddScoped<IInfoRepository>(serviceProvider =>
{
return new InfoRepository(
config["ConnectionStrings:MainConnection"],
config["ConnectionStrings:MetaDataConnection"],
config["InfoFunctionName"],
config["UserName"],
config["Password"],
config["VirtualHost"],
config["ConnectionHostName"]);
});
collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>();
var appServiceProvider = collection.BuildServiceProvider();
return appServiceProvider;
}
public static IWebHostBuilder BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseApplicationInsights()
.UseUrls("http://0.0.0.0:5003")
.UseNLog();
}
问题在于,您使用
BuildWebHost
创建的端点使用了自己的ServiceProvider
实例。您创建的ServiceProvider
实例未进入管道
原因:servicecolection
不使用任何类型的单例注册表,因此通过servicecolection
的某个实例注册服务并构建ServiceProvider
的某个实例是不够的。您必须使端点使用您的特定实例servicecolection
/ServiceProvider
。或者,您可以将您的ServiceCollection
复制到端点使用的集合中—我就是这样解决的
因此,让我们使用servicecolection
来注册您的服务(现在就是这样)。然后,我们不必执行collection.BuildServiceProvider()
,而是使用Startup
中的servicecolection
,将所有注册复制到管道使用的服务集合中
首先,让我们公开您的服务集合
,以便从启动
进行访问:
类程序
{
公共静态ServiceCollection AppServices{get;set;}
公共静态void Main(字符串[]args)
{
//…其他东西。。。
AppServices=GetServiceCollection(配置);
//…其他东西。。。
}
//从GetServiceProvider重命名
私有静态ServiceCollection GetServiceCollection(IConfiguration配置)
{
var collection=newservicecolection();
//…注册服务。。。
回收;
}
}
然后在Startup
类中,使用ConfigureServices()
中的Program.AppServices
,如下所示:
编辑:注意在Startup.cs中使用s的
//确保这些用法存在:
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.Extensions.DependencyInjection.Extensions;
....
公营创业
{
//……其他成员。。。
public void配置服务(IServiceCollection服务)
{
//…像services.AddMvc()这样的常见内容。。。
//添加此行:
服务.TryAdd(Program.AppServices);
}
//……其他成员。。。
}
问题在于,您使用BuildWebHost
创建的端点使用自己的ServiceProvider
实例。您创建的ServiceProvider
实例未进入管道
原因:servicecolection
不使用任何类型的单例注册表,因此通过servicecolection
的某个实例注册服务并构建ServiceProvider
的某个实例是不够的。您必须使端点使用您的特定实例servicecolection
/ServiceProvider
。或者,您可以将您的ServiceCollection
复制到端点使用的集合中—我就是这样解决的
因此,让我们使用servicecolection
来注册您的服务(现在就是这样)。然后,我们不必执行collection.BuildServiceProvider()
,而是使用Startup
中的servicecolection
,将所有注册复制到管道使用的服务集合中
首先,让我们公开您的服务集合
,以便从启动
进行访问:
类程序
{
公共静态ServiceCollection AppServices{get;set;}
公共静态void Main(字符串[]args)
{
//…其他东西。。。
AppServices=GetServiceCollection(配置);
//…其他东西。。。
}
//从GetServiceProvider重命名
私有静态ServiceCollection GetServiceCollection(IConfiguration配置)
{
var collection=newservicecolection();
//…注册服务。。。
回收;
}
}
然后在Startup
类中,使用ConfigureServices()
中的Program.AppServices
,如下所示:
编辑:注意在Startup.cs中使用
s的
//确保这些用法存在:
使用Microsoft.Extensions.DependencyInjection;
使用Microsoft.Extensions.DependencyInjection.Extensions;
....
公营创业
{
//……其他成员。。。
public void配置服务(IServiceCollection服务)
{
//…像services.AddMvc()这样的常见内容。。。
//添加此行:
服务.TryAdd(Program.AppServices);
}
//……其他成员。。。
}
Startup类是什么样子的?我不知道appServiceProvider是如何进入管道的…@felix-b我在最初的帖子中添加了Startup.cs。你说你看不到我的appServiceProvider是如何进入管道的。我假设设置collection.addScope()足以让软件了解并使用依赖项注入对象。我将在ConfigureServices方法中管理我的所有服务。。。。这就是这个方法的初衷,你的启动类是什么样子的?我不知道appServiceProvider是如何进入管道的…@felix-b我在最初的帖子中添加了Startup.cs。你说你看不到我的appServiceProvider是如何进入管道的。我假设设置collection.addScope()足以让软件了解并使用依赖项注入对象。我将在ConfigureServices方法中管理我的所有服务。。。。这就是这种方法的初衷谢谢你的文章Felix!我的服务对象上不存在TryAdd()方法。此外,Add()不起作用,AddService()o
public InfoController()
public class Program
{
#region fields and propetries
public IConfiguration Configuration { get; }
//# if DEBUG
//#endif
public static IConnection Connection { get; set; }
public static ITimeSeriesBusinessComponent TimeSeriesBusinessComponent { get; set; }
public static IInfoBusinessComponent InfoBusinessComponent { get; set; }
private static int counter;
#endregion fields and propetries
public static void Main(string[] args)
{
IConfiguration config = GetConfigurations();
ILogger logger = GetLogger();
ServiceProvider appServiceProvider = GetServiceProvider(config);
Parallel.Invoke
(
() =>
{
BuildWebHost(args).Build().Run();
},
() =>
{
//...
}
);
}
private static IConfiguration GetConfigurations()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json");
IConfiguration config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", true, true)
.Build();
return config;
}
private static ILogger GetLogger()
{
ILogger logger = new LoggerFactory().AddNLog().CreateLogger<Program>();
return logger;
}
private static ServiceProvider GetServiceProvider(IConfiguration config)
{
var collection = new ServiceCollection();
collection.AddLogging(configuration => configuration.AddNLog());
//...
collection.AddScoped<IInfoRepository>(serviceProvider =>
{
return new InfoRepository(
config["ConnectionStrings:MainConnection"],
config["ConnectionStrings:MetaDataConnection"],
config["InfoFunctionName"],
config["UserName"],
config["Password"],
config["VirtualHost"],
config["ConnectionHostName"]);
});
collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>();
var appServiceProvider = collection.BuildServiceProvider();
return appServiceProvider;
}
public static IWebHostBuilder BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseApplicationInsights()
.UseUrls("http://0.0.0.0:5003")
.UseNLog();
}
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Title = "My CLI"
});
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My CLI");
c.DocExpansion(Swashbuckle.AspNetCore.SwaggerUI.DocExpansion.None);
c.RoutePrefix = string.Empty;
});
app.UseMvc();
}
}