【问题标题】:What does lifetime scope mean in Application_StartApplication_Start 中的生命周期范围是什么意思
【发布时间】:2019-02-15 19:54:50
【问题描述】:

当我将带有 Autofac 的 DbContext 配置为“生命周期范围”时,则在请求范围内,这意味着它在请求结束时被处置。

但是,当我们在 MVC 应用程序的 Application_Start() 方法中从容器中获取 DbContext 时会发生什么?

我们有一个设置类被设置为单例:

builder.RegisterType<Settings>().As<ISettings>().SingleInstance();

Application_Start() 中,我们从容器中获取设置:

var settings = DependencyResolver.Current.GetService<ISettings>();

Settings 类依赖于 DbContext - 并且 DbContext 在生命周期范围内设置

我们知道这是一个captive dependency,但不认为这是一个问题,因为该类只使用一次上下文。

我担心DbContext 是否会释放其资源。

Application_Start() 中,我们是在请求的范围内还是在应用程序的范围内?

如果我们在应用程序的范围内,“生命周期范围”是否意味着在应用程序停止之前我们不会处理 DbContext

【问题讨论】:

  • 你是如何获得上下文的?你能分享一些代码吗?
  • @CyrilDurand 问题用代码示例扩展

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


【解决方案1】:

资源将在您的情况下部署的范围内释放,它是应用程序范围,因此当应用程序停止时资源将被释放。

在这种情况下,我会使用Func<Owned<DbContext>>,类似的东西:

public class Settings
{
    Settings(Func<Owned<DbContext>> contextFactory)
    {
        this._contextFactory = contextFactory;
    }
    private readonly Object _lock = new Object();
    private readonly Func<Owned<DbContext>> _contextFactory;

    private Boolean _isSettingsLoaded = true;
    private Int32 _settingsA;

    public Int32 SettingsA
    {
        get
        {
            this.EnsureSettingsLoaded();
            return _settingsA;
        }
    }


    private void EnsureSettingsLoaded()
    {
        if (!this._isSettingsLoaded)
        {
            lock (this._lock)
            {
                if (!this._isSettingsLoaded)
                {
                    using (Owned<DbContext> context = this._contextFactory())
                    {
                        // context.Value.DoSomething(); 
                    }
                    this._isSettingsLoaded = true;
                }
            }
        }
    }
}

【讨论】:

  • 我在想我可以简单地在 Application_Start(): using (var scope = resolver.Container.BeginLifetimeScope()) { var settings = DependencyResolver.Current.GetService&lt;ISettings&gt;(); }...想法中创建一个显式范围?
  • 它可能会工作,但强制依赖项仍然存在,您可能会在此范围之外使用已处置的组件而不会注意到它并在将来创建错误。 Func&lt;Owned&lt;X&gt;&gt; 恕我直言,这是一个更好的解决方案,如果您在 Settings 实现中更改某些内容,则不会出现错误。
  • 这是真的,但我想我会反对在这里引入对Autofac 的依赖。通常我们希望我们的类对 IoC 实现一无所知,不是吗?
  • 我同意你的观点,但不幸的是,据我所知,在 .net 框架中没有与 Owned 等价的东西。 Owned 仅用于帮助处理您不知道它是否实现 IDisposable 的对象。在您的情况下,如果您注入 IDisposable 的 DbContext,您可以忘记 Owned。另一种解决方案是在您的核心框架中使用 Owned 等效项。顺便说一句,我宁愿依赖 * Autofac* 而不是强制依赖。
猜你喜欢
  • 2023-03-29
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
相关资源
最近更新 更多