Represents a request for a dependency (or service) that the target class receives from its constructors, typically from a dependency injection container such as Microsoft.Extensions.DependencyInjection.
Namespace: PostSharp.Aspects.Advices
Assembly: PostSharp.dll
Syntax
public sealed class ImportDependencyAdviceInstance : AdviceInstanceRemarks
An aspect returns an ImportDependencyAdviceInstance from ProvideAdvices(object), so that the request can depend on the configuration of the target. The target class is the class to which the aspect is applied, or the declaring class of the member to which it is applied. For each target class, the request does the following:
- If the class declares or inherits a field of the dependency type that it can access, the request resolves to this field, and nothing else changes. Otherwise, if the class declares or inherits a readable instance property of the dependency type that it can access, the request resolves to this property in the same way; several such properties cause the error LA0286. The field or the property is trusted: the request does not check that the class initializes it.
- Otherwise, a private read-only field of the dependency type is introduced, as an IntroduceFieldAdviceInstance without a name and with Ignore does. When the field is not private, as specified by Visibility, or when the dependency is lazy, the field stays private and a getter-only property of the dependency type exposes it. A class whose base class exposes the same dependency by such a property uses that property.
- A parameter of the dependency type is appended to the instance constructors of the class, and to those of the classes
that derive from it, whose
base(...)calls pass it, also when they are in another assembly that PostSharp processes. A constructor that already has a parameter of exactly the dependency type uses it. - Each original constructor is kept as a forwarder that passes
nullfor the dependency. Apublicforwarder becomesprotected internal, orinternalin a sealed class, so that a dependency injection container sees only the constructors that receive the dependency, while the code of the assembly and the derived classes in other assemblies can still call it. - The constructors assign the field just after the base constructor call, as C# assigns a field from a constructor
parameter, and before the aspects are initialized and the body of the constructor runs. When the argument is
null, the dependency is resolved from RunTimeServiceLocator: GetRequiredService<T>() for a required dependency, which throws InvalidOperationException when no service is registered, and GetService<T>() for an optional one.
The advices of the aspect instance that made the request receive the dependency through a parameter annotated with
ImportMemberAttribute: by the Name of the request, whatever the names of the field and of the property, or
without a name, by the dependency type. The parameter receives the property when there is one, and the field otherwise. On a static
target, it receives null.
An object of the class can still be created with new in the project, through a forwarder: its dependencies are then
resolved from RunTimeServiceLocator, where the application registers a factory for each
service. The request also works with OnInstanceConstructedAdvice: the dependencies are assigned before the advice
runs.
Applying such an aspect to a public class changes its public constructors. This is a binary breaking change for the consumers of the class. Several requests for the same dependency type in a class give one field and one parameter, which is required when one of the requests is.
Constructors
| Name | Description |
|---|---|
| ImportDependencyAdviceInstance(Type) | Initializes a new instance of the ImportDependencyAdviceInstance class. |
Properties
| Name | Description |
|---|---|
| DependencyType | Gets the type of the dependency. |
| IsLazy | Gets or sets a value indicating whether the dependency is resolved when it is first used rather than when the object is created. A lazy
dependency is received as a Lazy<T> of the dependency type, stored in a field of that type, and exposed by a getter-only
property of the dependency type that returns Value. The container must be able to create the
Lazy<T>. The default value is |
| IsRequired | Gets or sets a value indicating whether the dependency is required. The default value is |
| MasterAspectMember | Gets the main field or method of the aspect class that the current AdviceInstance relates to. |
| Name | Gets or sets the name by which the advices of the aspect import the dependency with ImportMemberAttribute, and the name of the
property that exposes it, or |
| Visibility | Gets or sets the visibility of the member that exposes the dependency, or |