.NET 中的服务生命周期

作者:微信公众号:【架构师老卢】
4-19 14:19
38

概述:今天,我们将深入探讨 .NET Core 依赖项注入 (DI) 框架中的服务生存期,这对于构建可靠且高效的应用程序至关重要。服务的创建、共享和处置方式会影响应用程序中资源的性能和管理。了解服务生命周期在我们开始卷起袖子深入研究一些真实示例之前,我们应该首先澄清一些事情,即我们在谈论服务寿命时的含义。.NET Core 中的主要服务生存期如下所示:单一实例:在应用程序的生命周期内创建和共享。作用域:作用域内的每个请求创建一次。瞬态:在每次请求时重新创建。但不仅仅是这些生命会改变它。他们还将确定服务如何适应应用程序的其他部分。从字面上看,这项权利可以是应用程序的“生死攸关”的情况,可以在负载下平稳

今天,我们将深入探讨 .NET Core 依赖项注入 (DI) 框架中的服务生存期,这对于构建可靠且高效的应用程序至关重要。服务的创建、共享和处置方式会影响应用程序中资源的性能和管理。

了解服务生命周期

在我们开始卷起袖子深入研究一些真实示例之前,我们应该首先澄清一些事情,即我们在谈论服务寿命时的含义。.NET Core 中的主要服务生存期如下所示:

  • 单一实例:在应用程序的生命周期内创建和共享。
  • 作用域:作用域内的每个请求创建一次。
  • 瞬态:在每次请求时重新创建。

但不仅仅是这些生命会改变它。他们还将确定服务如何适应应用程序的其他部分。从字面上看,这项权利可以是应用程序的“生死攸关”的情况,可以在负载下平稳运行或失败。

为什么这很重要?

使用寿命的选择会影响:

  • 内存使用率:占用大量资源的单例服务可能会导致内存使用量增加。
  • 应用程序性能:滥用作用域服务或瞬态服务可能会导致不必要的分配和垃圾回收。
  • 并发问题:单例服务需要线程安全,这增加了设计的复杂性。

真实世界的例子

现在,让我们探讨一些方案,这些方案说明了服务生存期的影响以及如何选择正确的生存期。

方案 1:以单一实例形式记录

Singleton 服务的常见用例之一是日志记录。通常,它具有横切关注点,因此它需要在应用程序的整个生命周期中都可用,并且通常,它被设计为线程安全的。

public interface ILogger  
{  
    void Log(string message);  
}  
  
public class FileLogger : ILogger  
{  
    public void Log(string message)  
    {  
        // Implementation writing to a file  
    }  
}  
  
// In Startup.cs or Program.cs  
services.AddSingleton\<ILogger, FileLogger>();

这可确保您的应用程序使用一个 FileLogger 实例,从而降低资源利用率,并使用于访问日志文件的实例保持一致。

方案 2:按范围显示的数据上下文

在使用 Entity Framework Core 进行 Web 应用程序中的数据访问时,应注意管理 DbContext 的生存期。通过将其作为作用域服务执行此操作,它可确保每个请求仅创建和释放一次对象,从而调整生存期语义并避免并发访问的派生问题。

public class MyDataContext : DbContext  
{  
    // DbContext implementation  
}  
  
// In Startup.cs or Program.cs  
services.AddScoped<MyDataContext>();

使用此设置,它确实意味着数据库操作的上下文实例可以在请求中共享;因此,确保数据一致性和事务完整性。

场景 3:控制台应用程序中的依赖注入

它在构建控制台应用程序时没有内在请求范围,就像在 Web 应用程序中一样。但是,仍然可以通过手动创建作用域来使用作用域服务。

var serviceProvider = new ServiceCollection()  
    .AddScoped<MyService>()  
    .BuildServiceProvider();  
  
using (var scope = serviceProvider.CreateScope())  
{  
    var service = scope.ServiceProvider.GetRequiredService\<MyService>();  
    // Use the service  
}

它使长时间运行的应用程序或处理批量工作的应用程序在管理其资源时更加灵活。

选择服务寿命的提示

  • 对于轻量级服务,首选瞬态服务:如果服务是轻量级且无状态的,则暂时性是安全的默认值。
  • 对请求绑定资源使用 Scoped:对于绑定到请求生命周期的资源(如数据库上下文),Scoped 可确保正确清理它们。
  • 用于横切关注点的单例:日志记录、配置和类似的横切关注点是单例服务的理想候选者。

要避免的陷阱

  • 具有作用域依赖项的单例:切勿将作用域服务注入到单例服务中。这可能会导致意外行为和资源泄漏。
  • 过度使用单例:虽然单例很有用,但过度使用它们会导致内存膨胀和并发问题。

.NET Core DI 框架中的服务生存期是制作有效、可缩放的应用程序的一个重要方面。在项目中谨慎使用这些生存期,不要偶然发现导致应用程序松弛或性能不佳的常见陷阱。

相关留言评论
昵称:
邮箱:
阅读排行