解决“Singleton”中的InstancePerHttpRequest

时间:2013-09-30 20:31:23

标签: c# asp.net-mvc-4 dependency-injection autofac

我正在尝试在现有的MVC4应用程序中开始使用依赖注入。我安装了Autofac 3.1.1和Autofac MVC4集成3.1.0。到目前为止,我一直对它感到非常满意 - 但是,我对要求提供一次性服务的请求有困难:

namespace App_Start
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using Autofac;
    using Autofac.Integration.Mvc;

    public static class KernelConfig
    {
        private static IContainer Container { get; set; }

        public static void Register()
        {
            var builder = new ContainerBuilder();
            builder.RegisterControllers(typeof(MvcApplication).Assembly);

            builder.RegisterType<Bar>()
                   .As<IBar>()
                   .InstancePerHttpRequest();

            builder.RegisterType<Foo>()
                   .As<Foo>()
                   .SingleInstance();

            Container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(Container));
        }


        class Foo
        {
            private readonly IBar _bar;

            public Foo(IBar bar)
            {
                _bar = bar;
            }
        }

        interface IBar
        {
            void DoStuff();
        }

        class Bar : IBar, IDisposable
        {
            public void DoStuff() { }

            public void Dispose() { }
        }
    }
}

如果我在控制器构造函数中请求IBar实例,一切都按预期工作 - 每次都会生成一个新的Bar并且每次都会销毁。但是,如果我在我的控制器构造函数中请求Foo,我会收到以下消息:

  

“没有标记匹配'AutofacWebRequest'的范围可见   请求实例的范围“

据我所知,Autofac正在创建一个新的Foo作为单身人士。虽然这看起来很明显(我要求它是一个单例)但我希望Autofac能够遍历依赖树并在整个树中使用相同的生命周期。 (即,如果单例包含瞬态,那么两者都应该是瞬态的)

这是预期的行为吗?我做错了什么?

2 个答案:

答案 0 :(得分:0)

您可以使用依赖关系 IBarFactory 而不是 IBar IBarFactory 将具有sigleton生活方式,它将返回 IBar 实例,该实例将从容器中解析。

答案 1 :(得分:0)

抛出异常是因为代码试图在单个实例对象中解析InstancePerHttpRequest对象。

通过一些修改,您可以实现这一目标。

  1. 转换Foo以接受Func
  2. public class Foo {
        private readonly Func _barFunc;
    
        public Foo(Func barFunc) {
            _barFunc = barFunc;
        }
    }
    1. 使用DependencyResolver.Current对象解析Func
    2. builder.Register(c => new Foo(() => DependencyResolver.Current.GetService()))
         .As()
         .SingleInstance();

      有关Autofac范围的更多提示,请查看此链接 Autofac per request scope