2013-04-06 84 views
2

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

+0

您是否可以包含使用代码或至少使用注入依赖关系的ctor和example方法? – 2013-04-06 20:14:56

+0

没有回答这个问题,但我想说你的WalletRepository不应该需要IO初始化。尝试初次使用其中一种方法时首先使用它。 – usr 2013-04-06 20:31:51

+0

它不是使用IO初始化的存储库,而是一个Wallet对象(它们是从文件加载的)。 – Pein 2013-04-06 21:34:47

回答

6

除非我误认为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

一个选项是让注册做到将异步调用转换为结果所需的阻塞。

即:

这意味着AutoFac将被迫做阻塞时的依赖性都解决了,服务的客户端不需要知道服务工厂异步。

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

0

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