Registering async factory in Autofac

情到浓时终转凉″ 提交于 2019-12-07 05:11:04

问题


I have a Wallet class that I get from a repository. I'm trying to properly register both in Autofac so classes using the wallet could have a proper instance injected. The problem is that the repository uses an async method (returning Task). Does Autofac support such cases?

This doesn't work:

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

Somewhere in the app I just have:

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

When calling container.Resolve<ViewModel>() i get an exception saying Wallet is not registered.


回答1:


Unless I'm mistaken Autofac doesn't have any specific support for async factories. You can still make it work, but you have to write some boilerplate code, because constructor injection won't work. You also have to be more literal and say you want Task<T> instead of T. The whole code would look something like this:

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>>();

It's possible Autofac has some extensibility points to make this code simpler, but I don't know enough about it to help you with that.




回答2:


One option is just to make the registration do the blocking required to convert the async call into it's result.

ie:

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

This means that AutoFac will be forced to do the blocking when the dependencies are resolved, and the client of the service need not know that the service factory was async.

Whether this is a good idea will depend largely on what you are doing at the time of course.




回答3:


This might cause a deadlock. Autofac is using locks in some of the logic that handles the resolving for different lifetime scopes. so if the the async factory operation will try to resolve something in another thread you will get a deadlock



来源:https://stackoverflow.com/questions/15854245/registering-async-factory-in-autofac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!