我已经设置了一个带有.net核心类库项目和一个asp.net核心web api项目的解决方案。为了使用我的类库,我通过ConfigureServices添加了接口,其中DataRepo是类库中的一个类。
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IDataRepo, DataRepo>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
此类库需要获取将在API项目文件appsettings.json中的特定于环境的连接字符串。如何将配置设置传递给它?另外,我想在库项目中添加EF核心数据模型,而不是在API项目中注册DbContext,而是在我的库的构造函数中,使用连接信息与DbContext中的配置一起传递。首先,我如何从appsettings.json获取配置设置到我的类库?
namespace DataLib
{
public class DataRepo : IDataRepo
{
public DataRepo()
{
}
public string GetHello()
{
return "hello from lib";
}
}
}
lib项目不应该关心配置文件的位置。任何时候我们需要在我们的lib项目中进行配置,让我们说一个ConnectionString
,我们应该只是要求它。
首先要做的是在库项目中添加一个包引用:
<PackageReference Include="Microsoft.Extensions.Configuration" Version="2.1.1" />
然后在我们需要时注入IConfiguration
。例如,我们应该在IConfiguration
中注入一个DataLib
对象:
namespace DataLib
{
public class DataLib: IDataRepo
{
private readonly IConfiguration _configuration ;
public DataLib(IConfiguration config ){
this._configuration=config;
}
public string ConnectionString{
get{
return _configuration.GetConnectionString("DefaultConnection");
}
}
}
}
IConfiguration
不关心配置文件在哪里或者在启动时通过命令行传递哪种参数。实际上,它并不关心任何事情。 DataLib只使用一个简单的POCO。
当我们需要主项目中的类库时,我们可以通过以下方式将服务添加到DI容器中:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.AddScoped<DataLib.DataLib>(); // if you want to use DbContext , just use AddScoped<TService>()
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
这就是我们所要做的。 appsettings.json
和其他配置将构建到IConfiguration
的实例中,然后自动注入lib项目。
如果您的类需要连接字符串,那么只需给它连接字符串。你可以利用AddScoped
的Action<T>
超载。
首先,添加一个带有连接字符串的构造函数:
public class DataRepo : IDataRepo
{
private readonly string _connectionString;
public DataRepo(string connectionString)
{
_connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString));
}
}
然后,在Startup.cs
:
services.AddScoped<IDataRepo>(p => new DataRepo(Configuration.GetConnectionString("Foo")));
你的班级不应该知道或关心连接字符串实际来自哪里,这就是为什么其他方法,例如注入IConfiguration
在这里是错误的。