【问题标题】:confusion over using transient or scoped or singleton in .NetCore在 .Net Core 中使用瞬态、作用域或单例的混淆
【发布时间】:2020-08-23 21:24:33
【问题描述】:

大家好,我是软件开发的新手,我仍然不知道什么时候使用哪个,服务寿命是什么意思!这可能看起来很愚蠢,但请帮助我,我有一个界面:

 public  interface IAccessInfo
{
    public IEnumerable<AccessInfo> getResult();
}

它应该做的是向我返回有关我的涡轮机的信息;这是它的实现:

 public class AcessInfoData:IAccessInfo
{
    private DbContextClass db;
    public AcessInfoData(DbContextClass context)
    {
        db = context;

    }
    public IEnumerable<AccessInfo> getResult()
    {     
    var turbines = (from c in db.accessinf                         
                      where s.user_id == "i0004912"
                        select new AccessInfo
                        {
                            InfoType = c.type,
                            TurbineId = c.m_plc_id.ToString(),
                            TurbineIP = c.turbine_ip.ToString(),
                            TurbineIdSorting = c.turbine_id,
                            Blade = c.blade,
                            Certification = c.certification,

                       }).Distinct();

        return turbines;

    }
}

它获取我的数据库实例并获取数据;在我的控制器中,我像这样使用它:

 public class AcessInfoController : ControllerBase
{

  private IAccessInfo _acess;
  public  AcessInfoController(IAccessInfo access)
    {
        _acess = access;       

    }
    [HttpGet]
    public IActionResult Index()
    {
        var rsult = _acess.getResult();
        return Ok( rsult);
    }
}

现在我在 Startup 中注册了它:

  services.AddScoped<IAccessInfo, AcessInfoData>();

它有效,但如果你 sk我为什么我使用 Scoped 而不是 Singleton 或瞬态我不知道为什么,真的,任何人都可以为我说清楚吗?

【问题讨论】:

  • 我很久以前写过一篇关于 .NET Core 中 DI 的文章:joonasw.net/view/aspnet-core-di-deep-dive 它可能会提供一些信息 :)
  • @juunas 我读到了,但是你能告诉我我应该选择哪个生命周期吗?在上述例子中?
  • 如果您的 DbContext 注册为 Scoped(EF Core 的默认值),那么您的类在此处可以是 Scoped 或 Transient。它不能是 Singleton,因为它的生命周期会比 Scoped 更长。
  • @juunas 是的,因为如果注册为单身人士我会出错!但是你能告诉我这个生命周期吗?你所说的更高生命周期是什么意思?
  • @juunas 如果将我的所有服务都注册为范围,会导致问题吗?

标签: asp.net-core


【解决方案1】:

我将尝试解释一下提到的案例:

作用域 :针对对象在操作生命周期中的所有需求(例如来自客户端的请求),创建了对象的单个实例。 (It means that only one instance of the object is sent for all requirements during life time of a request)

单例:只创建一个对象实例并将其发送给应用范围内的所有需求。(For all needs everywhere in the program, only one instance of the object is sent, a bit like static objects)

Transient:Ioc容器,在代码需要的时候创建一个对象的实例,也就是说,它在程序的任何地方,任何时间,为每个需求创建一个实例,这意味着如果程序需要一个对象 3 次,它为每个对象创建一个独立的实例。

实例:在这种情况下,每次需要一个对象时,只向程序提供它的一个实例,您在启动部分中定义了它。 (在启动部分定义它时,您指定如何创建实例)。

我希望减少一些歧义。

【讨论】:

  • 所以在我的例子中如果我选择 Singleton 会发生什么?
  • 这个很重要,当你将对象设置为单例时,实际上对象从程序开始到执行结束都停留在内存中,内存消耗量为对服务器很重要。此外,在大多数情况下,我们希望在需要一个对象时从头开始设置一个对象,但如果我们将其作为单例引入,这将是不可能的,依此类推。
  • @ilmagnifico,在您的示例中,在执行时,我们可能在运行过程中看不到太多变化,但是从站点开始运行到完成执行,您的对象将保留在服务器的内存中。考虑以这种方式定义不同对象的所有示例,然后您将填满服务器的 RAM。您将在服务器上运行 RAM,但我们并不总是为大型计算机构建站点。
  • 所以你的意思是,通过注册服务范围对服务器施加负载,对吗?
  • 不,我们必须从经验中学习哪些对象适合作用域,哪些对象需要创建单例。在许多情况下,作用域是更好的选择。
猜你喜欢
  • 2020-10-28
  • 2017-06-10
  • 2021-07-16
  • 2021-01-14
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多