我将此服务注入其他控制器。
它需要一个服务,以及一个从配置文件中获取的连接字符串。
public class MyService : IMyService
{
public MyService(IService1 service1, IService2 service2, string connectionString){
//...
}
}
我希望注入IService1
和IService2
,但需要手动指定connectionString
。我无法解决这个问题,我看到的例子要么是非常复杂,要么就是我想达到的目标。
public void ConfigureServices(IServiceCollection services)
{
var cfg = new MyConfiguration();
Configuration.Bind("config", cfg);
var connectionString = cfg["myConnectionString"];
services.AddSingleton<IMyService, MyService>(/*what can I do here?*/)
}
这可以简单地实现吗?
答案 0 :(得分:3)
您可以访问工厂代理中的服务提供商。
解析其他依赖项并在初始化服务时注入静态变量。
//...
var connectionString = cfg["myConnectionString"];
services.AddSingleton<IMyService>(_ =>
new MyService(_.GetService<IService1>(), _.GetService<IService2>(), connectionString));
在上面的示例中,工厂委托中的_
是IServiceProvider
,GetService<T>
扩展方法用于解析其他服务,只要它们也在服务集合中注册。< / p>
首次请求IMyService
时将调用工厂代理。
作为替代方案,引用Options pattern in ASP.NET Core
并假设例如 settings.json 文件
{
"myConnectionString": "value1_from_json",
}
考虑使用配置扩展提供的IOptions<T>
。
创建一个类来存储所需的配置。
public class MyConnections {
public string MyConnectionString { get; set; }
}
重构该类以依赖IOption<MyConnections>
public class MyService : IMyService {
private string connectionString;
public MyService(IService1 service1, IService2 service2, IOptions<MyConnections> options){
connectionString = options.Value.MyConnectionString;
//...
}
//...
}
并在启动时配置
//...
services.Configure<MyConnections>(Configuration);
services.AddSingleton<IMyService, MyService>();
答案 1 :(得分:1)
你可以像Nkosi建议的那样去做,并使用创建服务的工厂。但是这有一个缺点,即这是非常明确的,并且需要您在构造函数签名更改时始终调整对象创建(例如,当您需要不同的依赖项时)。
ASP.NET Core世界中更合适的解决方案是使用选项模式。您所做的基本上不是要求将连接字符串传递给构造函数,而是创建一个配置服务的新配置类型。然后,您可以使用选项模式配置此对象。
这看起来像这样:
ghc
然后在你的创业公司中,只需注册你的类型并配置选项:
public class MyService : IMyService
{
public MyService(IService1 service1, IService2 service2, IOptions<MyServiceOptions> serviceOptions)
{
var connectionString = serviceOptions.Value.ConnectionString;
//...
}
}
public class MyServiceOptions
{
public string ConnectionString
{ get; set; }
}
如果将连接字符串的配置放在单独的配置部分中,您甚至可以这样做:
services.AddSingleton<IMyService, MyService>();
services.Configure<MyServiceOptions>(options => {
options.ConnectionString = "connection string";
});
假设您的配置如下所示:
services.Configure<MyServiceOption>(configuration.GetSection("MyService"));