C#在构造函数中获取连接详细信息



我的DB类定义如下:

public class DbAdapterService : DbAdapterService
{
private readonly AppSettings _settings;
public DbAdapterService(IOptions<AppSettings> settings)
{
_settings = settings?.Value;
DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
builder.ConnectionString = _settings.ConnectionString;           
}
}

在上面的类中,我从appsettings.json中获取连接字符串,它运行良好。

现在,我们需要从类中定义的另一个方法中获取连接字符串username和password。此方法从我们存储的保险库中获取这些详细信息。示例如下:

public class CredentialsService : ICredentialsService 
{   
public Credentials GetDetails()
{
//return credentials
}
}

我的问题是,我可以在上面的DbAdapterService构造函数中调用这个方法吗?或者是否有更好的方法来处理这个问题。

感谢

--更新--

public class DbAdapterService : DbAdapterService
{
private readonly AppSettings _settings;
public ICredentialsService  _credentialsService;
private bool isInitialized = false;

public DbAdapterService(IOptions<AppSettings> settings, ICredentialsService  credentialsService)
{
_settings = settings?.Value;

_credentialsService = credentialsService;
if (!isInitialized)
{
Initialize(_credentialsService);
}

DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
builder.ConnectionString = _settings.ConnectionString;           
}

public void Initialize(ICredentialsService  credentialsService)
{
if (isInitialized)
return;
else
{
//credentialsService.GetDetails();
isInitialized = true;
}          

}
}

您似乎想要初始化构造函数中的连接字符串。如果您正在接触某个外部组件(例如文件系统、数据库或API(来检索值,那么这可能是一个异步操作。在构造函数中没有可靠的方法来调用异步方法。

那么,我们能做什么呢?没有规则规定我们必须在构造函数中执行。构造函数是一个方便的地方,因为它可以确保在调用任何其他方法时,初始化已经发生。但还有其他模式可以实现这一点。这里有一个:

public class DbAdapterService : IDbAdapterService
{
string _connectionString;
readonly AppSettings _settings;
readonly ICredentialsService _credentialsService;

public DbAdapterService(IOptions<AppSettings> settings,
ICredentialsService  credentialsService)
{
_settings = settings.Value;         
_credentialsService = credentialsService;         
}
async Task EnsureInitializedAsync()
{
if (!string.IsNullOrEmpty(_connectionString))
{
//no need to reinitialize
//unless the credentials might change during the lifecycle of this object
return; 
}
var credentials = await _credentialsService.GetDetailsAsync();
var builder = new DbConnectionStringBuilder(_settings.ConnectionString);
builder.Username = credentials.Username;
builder.Password = credentials.Password;
_connectionString = builder.ConnectionString;         
}
public async Task DoSomethingAsync()
{
await EnsureInitializedAsync();
//now you can use _connectionString here
}
}

关键部分是记住在任何需要使用连接字符串的方法中调用EnsureInitializedAsync((。但至少使用DbAdapterService的代码不必知道是否初始化连接字符串。

虽然这种模式对于非异步代码来说不是必要的,但它对于将来可能变成异步的操作来说非常好,如果连接的细节在运行时可能会发生变化,但对象是在配置IoC容器时构建的,那么这种模式更有意义。

你可以试试这个

public class DbAdapterService : DbAdapterService
{
private readonly AppSettings _settings;
private readonly ICredentialsService _credentialsService ;
public DbAdapterService(
IOptions<AppSettings> settings, 
ICredentialsService credentialsService )
{
_credentialsService= credentialsService ;
_settings = settings?.Value;
DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
builder.ConnectionString = _settings.ConnectionString;           
}
}

之后,您可以从credentialService 调用任何方法

或者短一点,如果你只需要凭证

private readonly AppSettings _settings;
private readonly Credentials _credentials;
public DbAdapterService(
IOptions<AppSettings> settings, 
ICredentialsService credentialsService )
{
_credentials= credentialsService.GetDetails();
_settings = settings?.Value;
DbConnectionStringBuilder builder = new DbConnectionStringBuilder();
builder.ConnectionString = _settings.ConnectionString;           
}

相关内容

最新更新