6

我有一个从存储库获得的 Wallet 类。我正在尝试在 Autofac 中正确注册两者,以便使用钱包的类可以注入适当的实例。问题是存储库使用异步方法(返回任务)。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>()我得到一个异常说钱包没有注册。

4

3 回答 3

10

async除非我弄错了 Autofac 对工厂没有任何特定的支持。你仍然可以让它工作,但你必须编写一些样板代码,因为构造函数注入不起作用。您还必须更加直截了当并说您想要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 可能有一些扩展点来简化此代码,但我对它的了解还不够,无法帮助您。

于 2013-04-06T23:34:51.610 回答
1

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

于 2015-05-13T10:57:34.543 回答
0

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

IE:

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

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

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

于 2015-02-11T05:49:12.973 回答