在Autofac中注册异步工厂

我有一个从存储库中获取的Wallet类。 我正在尝试在Autofac中正确注册,因此使用钱包的类可以注入适当的实例。 问题是存储库使用异步方法(返回Task)。 Autofac是否支持此类案例?

这不起作用:

cb.RegisterType() .As() .SingleInstance(); cb.Register(async c => await c.Resolve().CreateAsync(App.WalletPath)); cb.RegisterType() .AsSelf(). .SingleInstance(); 

在应用程序的某个地方我只有:

 class ViewModel { public ViewModel(Wallet wallet) { //nothing fancy here } } 

当调用container.Resolve()我得到一个例外,说钱包没有注册。

除非我弄错了Autofac对async工厂没有任何特定的支持。 您仍然可以使它工作,但您必须编写一些样板代码,因为构造函数注入将不起作用。 你还必须更加文字,并说你想要Task而不是T 整个代码看起来像这样:

 cb.RegisterType() .As() .SingleInstance(); cb.Register(c => c.Resolve().CreateAsync(App.WalletPath)); cb.Register(async c => new ViewModel(await c.Resolve>())) .SingleInstance(); var container = cb.Build(); var viewModel = await container.Resolve>(); 

Autofac可能有一些扩展点可以使这个代码更简单,但我不太了解它可以帮助你。

一种选择只是使注册执行将异步调用转换为结果所需的阻塞。

即:

 cb.Register(c => c.Resolve().CreateAsync(App.WalletPath).Result); // nb: blocking call 

这意味着在解析依赖关系时,AutoFac将被强制执行阻止,并且服务的客户端不需要知道服务工厂是异步的。

这是否是一个好主意在很大程度上取决于你当然正在做什么。

这可能会导致死锁。 Autofac在一些处理不同生命周期范围的解析的逻辑中使用锁。 因此,如果异步工厂操作将尝试解析另一个线程中的某些内容,则会出现死锁