Autofac注入的实例不能用作单例

时间:2014-08-18 09:48:28

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

我使用Autofac注册必要的类型 InstancePerLifetimeScope

builder.RegisterType<WebSecurityContext>()
                .AsSelf()
                .InstancePerLifetimeScope();

并通过界面解析:

builder.Register<IApplicationContext>(context =>
            {
                return context.Resolve<WebSecurityContext>();
            })
            .As<IApplicationContext>();

我在我的WebAPI控制器中注入了ApplicationContext:

public class MedicalCenterController : BaseApiController
{
    private readonly IApplicationContext applicationContext;

    public MedicalCenterController(IApplicationContext applicationContext)
    {
        this.applicationContext = applicationContext;
    }

ApplicationContext具有 MedicalCenterId 值。在UI上选择新的医疗中心后,该值应该会改变。

更改MedicalCenterId发生在动作过滤器中,该过滤器还包含必要的上下文。

public class MedicalCenterAttribute : ActionFilterAttribute
{
    public IApplicationContext ApplicationContext
    {
        get;
        set;
    }

    public override void OnActionExecuting(HttpActionContext filterContext)
    {
        .....
        ApplicationContext.SetMedicalCenterId(medicalCenterId);
    }
}

但在此之后,ApplicationContext继续在MedicalCenterController和其他控制器中具有MedicalCenterId的先前值。

为什么autofac在不同的类中使用不同的实例,尽管我使用 InstancePerLifetimeScope 对象?

感谢。

1 个答案:

答案 0 :(得分:2)

不要将终身范围与单身人士混为一谈。具有生命周期范围的实例将与单例类似,但仅在每个生命周期范围内。因此,从生命周期范围解析的依赖服务将获得相同的实例,但在另一个生命周期范围内解析的服务将获得不同的实例。

因此,使用ASP.NET中的Autofac,除了整个应用程序共享的全局/根生命周期范围之外,每个请求都会获得新的生命周期范围。由于您的案例中的应用程序上下文已在生命周期范围内注册,因此在每个请求中都会创建一个新的应用程对一个实例所做的更改只能在同一生命周期范围内的服务中看到,并且一旦请求完成就会丢失。

所以,不要将终身范围与单身人士混为一谈。必须使用SingleInstance注册单例,而不是InstancePerLifetimeScope。

更新,因为您正在寻找一种为每个用户设置“医疗中心ID”的方法,这是您不应该在Autofac中处理的事情。我的建议是ApplicationContext在某个特定于用户的商店中加载/存储该值。这样,无论何时查询MedicalCenterId,每个用户都会为其提供服务,而与您在容器中注册ApplicationContext的方式无关。