架构师_程序员_码农网

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 10550|回复: 1

[资料] Autofac 控制作用域和生命周期(Scope and Lifetime)

[复制链接]
发表于 2020-9-19 12:51:52 | 显示全部楼层 |阅读模式
一篇学习Autofac控制作用域和生命周期很好的文章,生命周期作用域等同于你应用中的一个工作单元,一个工作单元将会在开始时启动生命周期作用域,然后需要该工作单元的服务被从生命周期作用域中解析出。

Lifetime Scopes

创建Lifetme Scopes

手动创建作用域,并Disposal。 Lifetime scopes are disposable and they track component disposal, so make sure you always call “Dispose()”or wrap them in “using” statements.




给Lifetime Scopes打标签

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

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



Adding Registrations to a Lifetime Scope

Autofac 允许你在创建生命周期时添加“on the fly”。This can help you when you need to do a sort of “spot weld” limited registration override or if you generally just need some additional stuff in a scope that you don’t want to register globally. You do this by passing a lambda to BeginLifetimeScope() that takes a ContainerBuilder and adds registrations.(在创建生命周期时,注册额外的服务,而不需要全局注册)



实例范围(Instance Scope)

实例范围决定了一个实例在request之间怎么共享的。 当请求一个服务时,autofac可以返回单例(single instance scope),新的实例(per dependency scope),或者某种上下文的单例,如线程或者http请求(per lifetime scope)。 This applies to instances returned from an explicit Resolve() call as well as instances created internally by the container to satisfy the dependencies of another component.

  • Instance Per Dependency
  • Single Instance
  • Instance Per Lifetime Scope
  • Instance Per Matching Lifetime Scope
  • Instance Per Request
  • Instance Per Owned
  • Thread Scope


Instance Per Dependency

在别的容器中也叫transient’ or ‘factory’,在每次请求服务时都会返回一个独一无二的实例。 如果没有指定的生命周期,这是默认行为。



每一Resolve依赖时,都返回一个新的组件。



Single Instance

在所有请求和嵌套作用域内都会返回同一个实例。




Instance Per Lifetime Scope

这个作用域可以应用于嵌套作用域。per-lifetime scope组件在嵌套的作用域内最多有一个实例。 This is useful for objects specific to a single unit of work that may need to nest additional logical units of work. Each nested lifetime scope will get a new instance of the registered dependency.



当你解析per lifetime scope实例组件时,在每个嵌套的作用域(e.g. per unit of work),只有一个实例。


Instance Per Matching Lifetime Scope

这个与Instance Per Lifetime Scope类似,但是可以用更精确的实例共享控制。 当创建嵌套生命周期时,可以给该周期打上“标签”或者“名字”。A component with per-matching-lifetime scope will have at most a single instance per nested lifetime scope that matches a given name。这样可以创建scoped singleton,其中的嵌套周期就可以共享组件,而不需要创建全局的实例。

对单个unit of work很有用,如http请求,作为嵌套生命周期来创建。 If a nested lifetime is created per HTTP request, then any component with per-lifetime scope will have an instance per HTTP request. (More on per-request lifetime scope below.)

在大部分应用中,只需要一个层级的容器嵌套就可以代表unit of work。如果需要多个嵌套层级(如global->request->transaction),组件可以通过tag来创建在特定层级共享。



当开始一个嵌套生命周期时,tag就和该生命周期关联。You will get an exception if you try to resolve a per-matching-lifetime-scope component when there’s no correctly named lifetime scope.(如果解析不存的tag标识的生命周期,会出异常)。



Instance Per Request

一些应用类型自然的拥有“request”类型语义,如ASP.NET MVC。在这些应用类型中,拥有某种形式的“singleton per request”是很有帮助的。Instance per request builds on top of instance per matching lifetime scope by providing a well-known lifetime scope tag, a registration convenience method, and integration for common application types(每次请求获取一个实例,是通过提供一个well-known的生命周期tag,a registration convenience method, and integration for common application types来构建在per matching lifetime scope之上的). 本质上就是per matching lifetime scope。

这意味这如果没有当前请求,而你却去解析一个基于instance-per-request注册的组件时,就会抛出异常。 There is a detailed FAQ outlining how to work with per-request lifetimes.

http://autofac.readthedocs.org/en/latest/faq/per-request-scope.html



Instance Per Owned

Owned隐式的关系类型,创建了新的嵌套生命周期。可以通过 instance-per-owned注册,可以将依赖范围限制在宿主实例中。



在这个例子中,ServiceForHandler服务的的生命周期限制在宿主MessageHandler实例的生命周期中(In this example the ServiceForHandler service will be scoped to the lifetime of the owned MessageHandler instance.)。



Thread Scope

可以参考

https://autofac.readthedocs.io/en/latest/lifetime/instance-scope.html#id7

实战

我使用的是 Instance Per Lifetime Scope 模式。

在winform中,调用执行的话,每次都是用一个数据库上下文,如下图:

c8dcf6b7-511d-402d-aaf3-9b8069087336.jpg

_dbContext.GetHashCode();
13583655
_dbContext.GetHashCode();
13583655
_dbContext.GetHashCode();
13583655

在多线程和并发的情况下,使用同一个db上下文,在对数据库进行增删改查的时候会出现异常。

我想每次点击按钮,都让autofac返回一个新的对象,代码如下:


如下图:

e82fcd17-885e-4817-824a-20cb37486f41.jpg

(完)




上一篇:.NET/C# 给图片加平铺的水印文字
下一篇:ASP.NET 禁止日志文件通过Url形式访问
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
发表于 2022-9-8 09:58:24 | 显示全部楼层
正是我们需要的
码农网,只发表在实践过程中,遇到的技术难题,不误导他人。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

免责声明:
码农网所发布的一切软件、编程资料或者文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:help@itsvse.com

QQ|手机版|小黑屋|架构师 ( 鲁ICP备14021824号-2 )|网站地图

GMT+8, 2024-4-18 21:01

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表