Autofac解决了当前Web请求范围内的问题

时间:2016-05-12 14:10:44

标签: c# asp.net-web-api2 autofac

我上课时在WebApi项目中设置Autofac,它看起来像:

public static class Bootstraper
    {
        private static IContainer _container { get; set; }

        public static void Init()
        {
            var configuration = GlobalConfiguration.Configuration;
            var builder = new ContainerBuilder();

            // register WebAPI   
            builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
            builder.RegisterWebApiFilterProvider(configuration);
            builder.RegisterHttpRequestMessage(configuration);

            // register MVC
            builder.RegisterControllers(Assembly.GetExecutingAssembly());
            builder.RegisterModule(new AutofacWebTypesModule());

            // register model class
            builder.RegisterType<Foo>().AsSelf().InstancePerRequest();
            builder.RegisterType<FooMessage>().AsSelf().InstancePerRequest();

            var container = builder.Build();

            // setup WebApi Autofac resolver
            var resolverAPI = new AutofacWebApiDependencyResolver(container);
            configuration.DependencyResolver = resolverAPI;

            // setup MVC Autofac resolver
            var resolverMVC = new AutofacDependencyResolver(container);
            DependencyResolver.SetResolver(resolverMVC);

            _container = container;
        }

        public static T Resolve<T>()
        {
            return _container.Resolve<T>();
        }

        public static T ResolveInScope<T>()
        {
            // where scope shoud by disposed?
            var scope = _container.BeginLifetimeScope(MatchingScopeLifetimeTags.RequestLifetimeScopeTag);
            return scope.Resolve<T>();
        }
    }

Foo FooMessage 类:

 public class FooMessage
    {
        public HttpRequestMessage Request {get; private set; }
        public Foo Foo { get; private set; }

        public FooMessage(HttpRequestMessage requestMessage, Foo fooo)
        {
            Request = requestMessage;
            Foo = fooo;
        }
    }

 public class Foo
    {
        public static int counter = 0;

        public int Index { get; private set; }
        public Foo()
        {
            Index = counter++;
        }
    }

为了显示我的问题,我准备了示例控制器

 
 public class ValuesController : ApiController
    {
        private FooMessage fooMessage;
        private Foo foo;

        public ValuesController(FooMessage fm, Foo fooo)
        {
            fooMessage = fm;
            foo = fooo;
        }


        // GET api/values
        public bool Get()
        {
            // it works but create new Foo object (resolvedFoo.Index > foo.Index)
            var resolvedFoo = DependencyResolver.Current.GetService<Foo>();

            // throw the exception 
            var resolvedFoo2 = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(Foo)) as Foo;

            // throw the Exception
            var resolvedFoo3 = Bootstraper.Resolve<Foo>();

            // it works but create new Foo object (resolvedFoo.Index > foo.Index)
            // and I don't now when dispose created scope
            var resolvedFoo4 = Bootstraper.ResolveInScope<Foo>();


            if (resolvedFoo.Index != foo.Index || resolvedFoo.Index != fooMessage.Foo.Index)
                return false;

            return true;
        }
    }

当创建ValuesController时,foo和fooMessage.Foo中的Index属性具有相同的值,它可以运行greate。我需要在我的bussines逻辑(InstancePerRequest)中解析Foo,FooMessage,特别是HttpRequestMessage,但我不能使用bussines构造函数来执行此操作。对于我的目的,最好的解决方案是使用Bootstraper.Resolve()但它抛出异常:

  

类型&#39; Autofac.Core.DependencyResolutionException&#39;的例外情况   发生在Autofac.dll但未在用户代码中处理

     

附加信息:没有标记匹配的范围   &#39; AutofacWebRequest&#39;从实例的范围可见   被要求了。这通常表示注册为的组件   SingleInstance()组件正在请求每HTTP请求   (或类似场景。)在Web集成下始终请求   来自DependencyResolver.Current或的依赖项   ILifetimeScopeProvider.RequestLifetime,永远不会从容器中   本身。

请帮助我理解它是如何工作的。

0 个答案:

没有答案