在Autofac中注册异步工厂

时间:2013-04-06 18:01:30

标签: c# autofac async-await c#-5.0

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

这不起作用:

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

应用程序中的某个地方我只是:

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

致电container.Resolve<ViewModel>()时,我收到一条例外消息称钱包未注册。

3 个答案:

答案 0 :(得分:8)

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

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

Autofac可能有一些扩展点使这段代码变得更简单,但我对它的了解不足以帮助你解决这个问题。

答案 1 :(得分:0)

一个选项就是让注册执行将异步调用转换为结果所需的阻止。

即:

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

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

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

答案 2 :(得分:0)

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