我有一个UserRepository
,它依赖于IDynamoDbClientFactory
。问题是IDynamoDbClientFactory
有一个方法,而且是异步的。ServiceCollections DI框架不允许我有一个异步提供程序。我不允许更改DynamoDbClientFactory
,因为它在外部库中。
我如何以比下面使用.GetAwaiter().GetResult()
所做的更好的方式处理这个问题?
services.AddSingleton<IDynamoDbClientFactory, DynamoDbClientFactory>();
services.AddSingleton<IUserRepository>(provider =>
{
var dbClientFactory = provider.GetRequiredService<IDynamoDbClientFactory>();
var dynamoDb = dbClientFactory.GetClientAsync().GetAwaiter().GetResult();
return new UserRepository(dynamoDb);
});
我找到了this similar question,它建议使用适配器来隐藏应用程序代码中的异步操作。
为了简单起见,我删除了不重要的代码。
第一次
以下是未使用的。
// The adapter hides the details about GetClientAsync from the application code.
// It wraps the creation and connection of `MyClient` in a `Lazy<T>`,
// which allows the client to be connected just once, independently of in which order the `GetClientAsync`
// method is called, and how many times.
public class DynamoDbClientAdapter : IDisposable
{
private readonly Lazy<Task<IDynamoDbClientFactory>> _factories;
public DynamoDbClientAdapter(IConfiguration configuration)
{
_factories = new Lazy<Task<IDynamoDbClientFactory>>(async () =>
{
var client = new DynamoDbClientFactory(configuration);
await client.GetClientAsync();
return client;
});
}
public void Dispose()
{
if (_factories.IsValueCreated)
{
_factories.Value.Dispose();
}
}
}
1条答案
按热度按时间ygya80vv1#
请尝试以下操作:
其中
DynamicClientUserRepositoryAdapter
是Composition Root中的一个适配器,它根据所需的IAmazonDynamoDB
按需创建真实的的UserRepository
:注意:我假设
IAmazonDynamoDB
不是线程安全的,这就是我将DynamicClientUserRepositoryAdapter
注册为作用域的原因。为什么要设计这样的东西的理由在the answer中解释,你已经在你的问题中提到了。