作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想调用 awaitable async
注册过程中的方法是这样的:
// builder variable contains Autofac ContainerBuilder
builder.Register(
(async (context, parameters) => // need async here
{
var someClass = new SomeClass(context.Resolve<ISomeDependency>());
await someClass.SomeAsyncInitMethod(); // need to await result
return someClass;
})).As<ISomeClass>().SingleInstance();
SomeClass
工具 ISomeClass
作为服务。重要的部分是 someClass.SomeAsyncInitMethod()
称呼。这是 async
,因此我需要 await
它在这里并把async
关键词进入Register
方法。但是现在Autofac
认为这会返回一个 Task<SomeClass>
不能注册为 Service
ISomeClass
.
如何实现以上并注册SomeClass
作为ISomeClass
在等待 async
时初始化方法?
最佳答案
我认为在解析阶段进行任何 I/O 密集型工作都是错误的设计,因为完全控制此操作的顺序、捕获它们的异常、重复它们、控制它们之间的时间等通常很重要.
解决方案是通过工厂推迟它们。让我用更有意义的 NpgsqlConnection
替换 SomeClass
:
var builder = new ContainerBuilder();
builder.Register(context =>
{
// make sure not to capture temporary context:
// https://autofaccn.readthedocs.io/en/latest/advanced/concurrency.html#service-resolution
var connectionString = context.Resolve<IConfiguration>().GetConnectionString("MyDb");
return new Func<Task<NpgsqlConnection>>(async () =>
{
var connection = new NpgsqlConnection(connectionString);
await connection.OpenAsync();
return connection;
});
});
下面是连接用户的样子:
public sealed class Repository
{
private readonly Func<Task<NpgsqlConnection>> _connectionFactory;
public Repository(Func<Task<NpgsqlConnection>> connectionFactory)
{
_connectionFactory = connectionFactory;
}
public async Task<string> GetServerVersionAsync()
{
using (var openedConnection = await _connectionFactory())
return openedConnection.ServerVersion;
}
}
即使 Autofac 支持异步注册,在 Repository
构造函数中要求一个工厂仍然是有益的,因为连接是一种有限的资源,最好限制它打开的时间.
关于c# - 如何在 Autofac 注册中调用异步方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38242662/
我是一名优秀的程序员,十分优秀!