【问题标题】:Resolving InstancePerHttpRequest inside "Singleton"在“单例”中解析 InstancePerHttpRequest
【发布时间】:2013-10-06 20:25:41
【问题描述】:

我正在尝试在现有的 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 遍历依赖树并在整个树中使用相同的生命周期。 (即如果一个单例包含一个瞬态,那么两者都应该是瞬态的)

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

【问题讨论】:

  • 单例不能包含瞬态。容器不会与基于一个消费者配置的生命周期不同,因为依赖项可以有多个消费者。如果一个依赖项要被单例使用,它本身应该被配置为单例。瞬态当然也可以使用单例依赖。

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


【解决方案1】:

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

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

  1. 将 Foo 转换为接受 Func
公共类 Foo {
    私有只读函数_barFunc;

    公共 Foo(Func barFunc) {
        _barFunc = barFunc;
    }
}
  1. 使用 DependencyResolver.Current 对象解析 Func
builder.Register(c => new Foo(() => DependencyResolver.Current.GetService()))
   。作为()
   .SingleInstance();

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

【讨论】:

    【解决方案2】:

    您可以使用对IBarFactory 的依赖来代替IBarIBarFactory 将具有 sigleton 生活方式,它将返回 IBar 实例,该实例将从容器中解析。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-12
      相关资源
      最近更新 更多