Autofac scope lifetime issue

匿名 (未验证) 提交于 2019-12-03 09:05:37

问题:

I have ASP.NET MVC application where I registered a component with an InstancePerHttpRequest scope.

builder.RegisterType<Adapter>().As<IAdapter>().InstancePerHttpRequest(); 

then I have an async piece of code where I'm resolving the Adapter component.

The following code is simplified

Task<HttpResponseMessage> t = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(t =>        // IHandleCommand<T> takes an IAdapter as contructor argument       var h = DependencyResolver.Current.GetServices<IHandleCommand<T>>(); ); 

The code above is throwing an exception: The request lifetime scope cannot be created because the HttpContext is not available.

So I did some research on the subject and found this answer https://stackoverflow.com/a/8663021/1003222

Then I adjusted the resolving code to this

 using (var c= AutofacDependencyResolver.Current.ApplicationContainer.BeginLifetimeScope(x => x.RegisterType<DataAccessAdapter>().As<IDataAccessAdapter>).InstancePerLifetimeScope()))  {        var h = DependencyResolver.Current.GetServices<IHandleCommand<T>>();  } 

But the exception stayed the same. The request lifetime scope cannot be created because the HttpContext is not available.

Am I missing something ?

回答1:

you can try something like this:

using (var c= AutofacDependencyResolver.Current                                        .ApplicationContainer                                        .BeginLifetimeScope("AutofacWebRequest")) {    var h = DependencyResolver.Current.GetServices<IHandleCommand<T>>(); } 


回答2:

Autofac tries to resolve the container from the MVC Dependency Resolver, If you have a async operation the httpContext won't be available so DependencyResolver won't be available either.

One option in to make the container available in a static variable or a proper instance, and create a context scope for this operation.

public static IContainer Container 

once you have the builder setup, copy the container

public class ContainerConfig {     public static IContainer Container;     public static void RegisterComponents()     {         var builder = new ContainerBuilder();         builder.RegisterInstance(new Svc()).As<ISvc>();         Container = builder.Build();         DependencyResolver.SetResolver(new AutofacDependencyResolver(Container ));     } }     

then when resolving use the static container config to create the instance you need.

using (var scope = ContainerConfig.Container.BeginLifetimeScope()) {        result = ContainerConfig.Container.Resolve<T>(); } 

hope it helps



回答3:

//On Startup Class public static IContainer Container { get; private set; }  public void Configuration(IAppBuilder app) {    ...    var builder = new ContainerBuilder();    builder.RegisterModule([yourmodules]);    ...    var container = builder.Build();    Container = container; } 

Then, when you need your instance:

using (var scope = Container.BeginLifetimeScope()) {                                    YourInterfaceImpl client = Container.Resolve<YourInterface>();    ... } 

Hope this help!



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