Fra*_*hop 1 c# dependency-injection asp.net-web-api .net-core
我有一个控制台应用程序,它的工作原理像网络api一样退出。我在Program.cs上注册
var collection = new ServiceCollection();
collection.AddScoped<IInfoBusinessComponent, InfoBusinessComponent>();
Run Code Online (Sandbox Code Playgroud)
在添加InfoBusinessComponent之前,InfoBusinessComponent还需要进行依赖项注入。我也注册我的ILogger。
在我的InfoController上,我像这样使用di:
public InfoController(IInfoBusinessComponent businessComponent, ILogger<InfoController> logger)
Run Code Online (Sandbox Code Playgroud)
当我现在呼叫该端点时,我立即收到500响应。当我从控制器中删除参数时,该过程将进入构造函数和控制器。但这不是我想要的。
public InfoController()
Run Code Online (Sandbox Code Playgroud)
为什么构造函数没有得到依赖注入或为什么没有调用构造函数?
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();
}
Run Code Online (Sandbox Code Playgroud)
这里是Startup.cs:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
问题是您创建的端点BuildWebHost
使用自己的实例ServiceProvider
。ServiceProvider
您创建的实例不会进入管道。
原因: ServiceCollection
不使用任何类型的单例注册表,因此仅通过的某个实例注册服务ServiceCollection
并构建的某个实例还不够ServiceProvider
。您必须使端点使用ServiceCollection
/ 的特定实例ServiceProvider
。或者,您可以将您的文件复制ServiceCollection
到端点使用的文件中-这就是我要解决的方法。
因此,让我们使用a ServiceCollection
来注册您的服务(现在为止)。然后,而不是做collection.BuildServiceProvider()
,我们使用的是ServiceCollection
在Startup
向所有注册复制到由管道使用的服务集合。
首先,让我们公开您的ServiceCollection
访问权限Startup
:
class Program
{
public static ServiceCollection AppServices { get; set; }
public static void Main(string[] args)
{
// ...other stuff...
AppServices = GetServiceCollection(config);
// ...other stuff...
}
// renamed from GetServiceProvider
private static ServiceCollection GetServiceCollection(IConfiguration config)
{
var collection = new ServiceCollection();
// ... register services...
return collection;
}
}
Run Code Online (Sandbox Code Playgroud)
然后在Startup
类中,使用Program.AppServices
中ConfigureServices()
,如下所示:
编辑:注意using
Startup.cs中的s
// make sure these usings are present:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
....
public class Startup
{
// ... other members ...
public void ConfigureServices(IServiceCollection services)
{
// ... the usual stuff like services.AddMvc()...
// add this line:
services.TryAdd(Program.AppServices);
}
// ... other members ...
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
64 次 |
最近记录: |