autofac 作用域_Autofac笔记-LifeTimeScope(生命周期范围)

本文介绍了Autofac中的生命周期范围(Lifetime Scope),包括服务范围、生命周期和如何手动创建及管理生命周期范围。生命周期范围是应用程序的工作单元,用于跟踪一次性组件的解析和释放,避免内存泄漏。还讲解了不同类型的实例范围,如瞬时、单例和Per Lifetime Scope,并讨论了如何通过标签进行更精细的控制,以便在事务级别共享服务。
摘要由CSDN通过智能技术生成

服务范围:

实例范围决定了在同一服务的请求之间如何共享实例。服务的范围是应用程序中可以与使用该服务的其他组件共享该服务的区域。例如,在您的应用程序中,您可能具有全局静态单例-该全局对象实例的“范围”将是整个应用程序。

服务生命周期:

服务的生命周期是服务实例在程序中生存的时间。例如您“新建”一个实现IDisposable的对象,然后再对其进行调用Dispose()。

Lifetime Scope(生命周期范围):

Autofac中生命周期范围的概念结合了这两个概念。实际上,生命周期范围等同于应用程序中的一个工作单元。一个工作单元可以在开始时开始一个生命周期范围,然后该工作单元所需的服务将从一个生命周期范围得到解析。当您解析服务时,Autofac跟踪已解析的一次性(可配置)组件。在工作单元结束时,您将释放相关的生命周期范围,Autofac将自动清理/释放解析后的服务。

务必始终从生命周期范围而不是根容器来解析服务。由于生命周期作用域的处置跟踪特性,如果您从容器(“根生命周期作用域”)中解析许多可丢弃组件,您可能会无意中给自己造成内存泄漏。根容器将一直保存对这些可丢弃组件的引用,直到其存在(通常是应用程序的生存期),因此它可以释放这些组件。

手动创建作用域:

您可以通过BeginLifetimeScope()从根容器开始在任何现有生存期范围上调用方法来创建生存期范围。生命周期范围是一次性的,并且它们跟踪组件的处置,因此请确保始终调用“ Dispose()”或将它们包装在“ using”语句中。

using(var scope = container.BeginLifetimeScope())

{

//从容器的一个子作用域解析服务

var service = scope.Resolve();

// 还可以创建嵌套的作用域

using(var unitOfWorkScope = scope.BeginLifetimeScope())

{

var anotherService = unitOfWorkScope.Resolve();

}

}

生命周期有以下几种:

瞬时(Per Dependency):每次请求都会创建新实例

builder.RegisterType().InstancePerDependency();

单例(Single Instance):所有对父容器或嵌套容器的请求都返回一个实例

builder.RegisterType().SingleInstance();

Per Lifetime Scope:

这个作用域适用于嵌套的生命周期。一个使用Per Lifetime 作用域的component在一个 nested lifetime scope内最多有一个实例。

当对象特定于一个工作单元时,这个非常有用。比如,一个HTTP请求,每一个工作单元都会创建一个nested lifetime,如果在每一次HTTP请求中创建一个nested lifetime,那么其他使用 per-lifetime 的component在每次HTTP请求中只会拥有一个实例。

builder.RegisterType().InstancePerLifetimeScope();

上下文

上下文作用域和per-lifetime作用域类似,但是对可见性提供更多显示的控制。

在大多数程序中,同一层次的容器嵌套代表一个工作单元,如果需要多层嵌套(例如global->request->transation),可以使用标签确保component在多层结构中的某一层共享。

builder.RegisterType().InstancePerMatchingLifetimeScope(MyContextHierarchy.UserSession);

提供的标签和生命周期作用域是对应的

var userSessionLifetime = container.BeginLifetimeScope();

userSessionLifetime.Tag = MyContextHierarchy.UserSession;

给Lifetime Scopes打标签:

有时候你可能需要在Unit of work内共享一些服务,但是又不希望采用全局的共享便利,如单例模式。例如web应用的per-request生命周期,在这中情况下你可以使用InstancePerMatchingLifetimeScope来标识你的生命周期和服务。

举例如下,有个发邮件的组件,事务逻辑中需要发送多次邮件,所以可以在每个逻辑事务片中共享邮件服务。然后不希望邮件组件成为全局单例,可以如下设置。

//将事务级共享组件注册为InstancePerMatchingLifetimeScope,并给它一个“已知标记”,在启动新事务时使用。

var builder = new ContainerBuilder();

builder.RegisterType()

.As()

.InstancePerMatchingLifetimeScope("transaction");

// 订单处理器和收据管理器都需要发送电子邮件通知。

builder.RegisterType()

.As();

builder.RegisterType()

.As();

var container = builder.Build();

// 用标记创建作用域范围

using(var transactionScope = container.BeginLifetimeScope("transaction"))

{

using(var orderScope = transactionScope.BeginLifetimeScope())

{

//IEmailSender将“驻留”在父事务作用域中,并且在作用域中的任何子作用域中共享

var op = orderScope.Resolve();

op.ProcessOrder();

}

using(var receiptScope = transactionScope.BeginLifetimeScope())

{

var rm = receiptScope.Resolve();

rm.SendReceipt();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值