A good article to learn about Autofac control scope and lifecycle, lifecycle scope is equivalent to a unit of work in your application, a unit of work will start the lifecycle scope at the beginning, and then the services that require that unit of work are parsed from the lifecycle scope.
Lifetime Scopes
Create Lifetme Scopes
Create a scope manually and Disposal. Lifetime scopes are disposable and they track component disposal, so make sure you always call “Dispose()”or wrap them in “using” statements.
Label Lifetime Scopes
Sometimes you may need to share some services within a Unit of work, but you don't want to use global sharing conveniences, such as singleton mode. For example, the per-request lifecycle of a web application, in which case you can use InstancePerMatchingLifetimeScope to identify your lifecycle and service.
For example, there is a component that sends mail, and the transaction logic needs to send messages multiple times, so the mail service can be shared in each logical transaction slice. If you don't want the email component to be a global singleton, you can set it as follows.
Adding Registrations to a Lifetime Scope
Autofac allows you to add "on the fly" when creating a lifecycle. 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. (When creating a lifecycle, register additional services without global registration)
Instance Scope
The instance scope determines how an instance is shared between requests. When requesting a service, autofac can return a single instance scope, a new instance per dependency scope, or a singleton in a context, such as a thread or an HTTP request 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
Also called transient' or 'factory' in other containers, it returns a unique instance each time a service is requested. If there is no lifecycle specified, this is the default behavior.
Each Resolve dependency returns a new component.
Single Instance
The same instance is returned across all requests and nested scopes.
Instance Per Lifetime Scope
This scope can be applied to nested scopes. The per-lifetime scope component has a maximum of one instance within the nested 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.
When you parse the per lifetime scope instance component, there is only one instance in each nested scope (e.g. per unit of work).
Instance Per Matching Lifetime Scope
This is similar to Instance Per Lifetime Scope, but control can be shared with more precise instances. When you create a nested lifecycle, you can label it or give it a name. A component with per-matching-lifetime scope will have at most a single instance per nested lifetime scope that matches a given name。 This allows for the creation of scoped singletons, where nested cycles can share components without creating global instances.
Useful for single units of work, such as http requests, created as nested lifecycles. 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.)
In most applications, only one hierarchical container nesting is needed to represent a unit of work. If multiple nested levels are required (e.g., global->request->transaction), components can be created to be shared at a specific level via tags.
When a nested lifecycle is started, tags are associated with that lifecycle. You will get an exception if you try to resolve a per-matching-lifetime-scope component when there’s no correctly named lifetime scope. (If the lifecycle of the unsaved tag is parsed, an exception will occur.)
Instance Per Request
Some application types naturally have a "request" type semantics, such as ASP.NET MVC. Among these application types, it is helpful to have some form of "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 (one instance per request is built on top of the per matching lifetime scope by providing a well-known lifetime tag, a registration convenience method, and integration for common application types). Essentially, it is per matching lifetime scope.
This means that if there is no current request, and you parse a component registered based on instance-per-request, an exception will be thrown. There is a detailed FAQ outlining how to work with per-request lifetimes.
The hyperlink login is visible.
Instance Per Owned
Owned implicit relationship type, creating a new nested lifecycle. Dependencies can be limited to the host instance by registering with instance-per-owned.
In this example, the ServiceForHandler service will be scoped to the lifetime of the owned MessageHandler instance.
Thread Scope
You can refer to it
The hyperlink login is visible.
Actual combat
I'm using the Instance Per Lifetime Scope mode.
In winform, when the call is executed, it uses a database context each time, as shown in the figure below:
_dbContext.GetHashCode();
13583655 _dbContext.GetHashCode();
13583655 _dbContext.GetHashCode();
13583655 In the case of multi-threading and concurrency, if you use the same db context, you will encounter exceptions when adding, deleting, modifying, or checking the database.
I want to have autofac return a new object every time I click the button, the code is as follows:
As shown below:
(End) |