X39.Util.DependencyInjection
2.0.1.8
dotnet add package X39.Util.DependencyInjection --version 2.0.1.8
NuGet\Install-Package X39.Util.DependencyInjection -Version 2.0.1.8
<PackageReference Include="X39.Util.DependencyInjection" Version="2.0.1.8" />
paket add X39.Util.DependencyInjection --version 2.0.1.8
#r "nuget: X39.Util.DependencyInjection, 2.0.1.8"
// Install X39.Util.DependencyInjection as a Cake Addin #addin nuget:?package=X39.Util.DependencyInjection&version=2.0.1.8 // Install X39.Util.DependencyInjection as a Cake Tool #tool nuget:?package=X39.Util.DependencyInjection&version=2.0.1.8
X39.Util.DependencyInjection
This library adds a simplified workflow for defining implementations for dependencies and adding them to a
dependency container.
It uses Reflection to find all classes in a given assembly which are attributed with either the
SingletonAttribute
, TransientAttribute
or ScopedAttribute
and adds them to the container.
It also allows for IConfiguration
based selection of active implementations by adding a static
method to the attributed class and adding a DepependencyInjectionConfigurationAttribute
to the method.
Semantic Versioning
This library follows the principles of Semantic Versioning. TThis means that version numbers and the way they change convey meaning about the underlying changes in the library. For example, if a minor version number changes (e.g., 1.1 to 1.2), this indicates that new features have been added in a backwards-compatible manner.
Note on Pre-Net7
This library is fully compatible with pre-.NET 7.0. However, there is a difference in how the attributes are used, since Net7.0 introduced generic attributes.
The changes pretty much are only in how the attributes have to be written,
eg. Singleton(typeof(Service), typeof(IService))
instead of Singleton<Service, IService>
.
This readme will only use the generic attributes. The non-generic attributes are working the same way.
Quick Start
Registering the services of an assembly
...
// ServiceCollection is the default container of .NET Core
// configuration is an IConfiguration instance
serviceCollection.AddAbstractAttributedServicesOf<TypeInThatAssembly>(configuration);
serviceCollection.AddAbstractAttributedServicesOf(configuration, assemblyReference);
[Singleton<Service, IService>] // This will make the service findable by the AddAbstractAttributedServicesOf method
public class Service : IService
{
}
Other than that, you may continue as usual with using dependency injection.
Attributes
SingletonAttribute<TService, [TAbstraction]>
This attribute marks a class as a singleton. When the AddAbstractAttributedServicesOf
method is called,
the class will be added to the container as a singleton either as the implementation of the interface.
Internally this means that for a given Singleton<TService, TAbstraction>
,
the method AddSingleton<TAbstraction, TService>()
will be called on the service collection.
Alternatively, the attribute can be used without the TAbstraction
parameter,
in which case the class will be added as a singleton without an interface
(AddSingleton<TService>()
for a given Singleton<TService>
).
Note that the XML documentation of the attributed class contains samples of how to use the attribute.
TransientAttribute<TService, [TAbstraction]>
This attribute marks a class as a transient. When the AddAbstractAttributedServicesOf
method is called,
the class will be added to the container as a transient either as the implementation of the interface.
Internally this means that for a given Transient<TService, TAbstraction>
,
the method AddTransient<TAbstraction, TService>()
will be called on the service collection.
Alternatively, the attribute can be used without the TAbstraction
parameter,
in which case the class will be added as a transient without an interface
(AddTransient<TService>()
for a given Transient<TService>
).
Note that the XML documentation of the attributed class contains samples of how to use the attribute.
ScopedAttribute<TService, [TAbstraction]>
This attribute marks a class as a scoped
When the AddAbstractAttributedServicesOf
method is called,
the class will be added to the container as a scoped either as the implementation of the interface.
Internally this means that for a given Scoped<TService, TAbstraction>
,
the method AddScoped<TAbstraction, TService>()
will be called on the service collection.
Alternatively, the attribute can be used without the TAbstraction
parameter,
in which case the class will be added as a scoped without an interface
(AddScoped<TService>()
for a given Scoped<TService>
).
Note that the XML documentation of the attributed class contains samples of how to use the attribute.
DepependencyInjectionConfigurationAttribute
This attribute marks a static method as a configuration method for the dependency injection.
When the AddAbstractAttributedServicesOf
method is called.
The method has to be in one of the following forms:
[DependencyInjectionCondition]
private static bool DICondition()
{
...
}
or
[DependencyInjectionConfiguration]
private static void DIConfiguration(IConfiguration configuration)
{
...
}
The method will be called on the initial setup of the dependency injection container once.
If the return value is false
, the class will not be added to the container.
As can be expected, the value of true
will add the class to the container.
Class Constructors
This method will always run any class constructor (if present) before adding the class to the container.
To quickly demonstrate this, consider the following class:
[Singleton<IService, Service>]
public class Service : IService
{
static Service()
{
Console.WriteLine("Class constructor called");
}
}
When the AddAbstractAttributedServicesOf
method is called, the following output will be produced:
Class constructor called
Project Notes
This project is part of my personal utility libraries i use in my projects. The following few paragraphs are meant to give you an overview of the project and how you can contribute to it.
Building
This project uses GitHub Actions for continuous integration. The workflow is defined in .github/workflows/main.yml
. It
includes steps for restoring dependencies, building the project, and publishing a NuGet package.
Test coverage
This project is not yet offering any tests. This is planned for the future, although due to the simplicity of the project, test coverage currently can be considered as not necessary (testing the project manually is sufficient to me).
If your project is required to have all libraries covered by tests, feel free to submit a pull request with tests.
Contributing
Contributions are welcome! Please submit a pull request or create a discussion to discuss any changes you wish to make.
Code of Conduct
Be excellent to each other.
Contributors Agreement
First of all, thank you for your interest in contributing to this project! Please add yourself to the list of contributors in the CONTRIBUTORS file when submitting your first pull request. Also, please always add the following to your pull request:
By contributing to this project, you agree to the following terms:
- You grant me and any other person who receives a copy of this project the right to use your contribution under the
terms of the GNU Lesser General Public License v3.0.
- You grant me and any other person who receives a copy of this project the right to relicense your contribution under
any other license.
- You grant me and any other person who receives a copy of this project the right to change your contribution.
- You waive your right to your contribution and transfer all rights to me and every user of this project.
- You agree that your contribution is free of any third-party rights.
- You agree that your contribution is given without any compensation.
- You agree that I may remove your contribution at any time for any reason.
- You confirm that you have the right to grant the above rights and that you are not violating any third-party rights
by granting these rights.
- You confirm that your contribution is not subject to any license agreement or other agreement or obligation, which
conflicts with the above terms.
This is necessary to ensure that this project can be licensed under the GNU Lesser General Public License v3.0 and that a license change is possible in the future if necessary (e.g., to a more permissive license). It also ensures that I can remove your contribution if necessary (e.g., because it violates third-party rights) and that I can change your contribution if necessary (e.g., to fix a typo, change implementation details, or improve performance). It also shields me and every user of this project from any liability regarding your contribution by deflecting any potential liability caused by your contribution to you (e.g., if your contribution violates the rights of your employer). Feel free to discuss this agreement in the discussions section of this repository, i am open to changes here (as long as they do not open me or any other user of this project to any liability due to a malicious contribution).
License
This project is licensed under the GNU Lesser General Public License v3.0. See the LICENSE file for details.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- JetBrains.Annotations (>= 2022.1.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 7.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- X39.Util (>= 1.0.0.33)
-
.NETStandard 2.1
- JetBrains.Annotations (>= 2022.1.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 7.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- X39.Util (>= 1.0.0.33)
-
net6.0
- JetBrains.Annotations (>= 2022.1.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 7.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- X39.Util (>= 1.0.0.33)
-
net7.0
- JetBrains.Annotations (>= 2022.1.0)
- Microsoft.Extensions.Configuration.Abstractions (>= 7.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 7.0.0)
- X39.Util (>= 1.0.0.33)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on X39.Util.DependencyInjection:
Package | Downloads |
---|---|
X39.Util.Blazor.WebAssembly
Utility services and components useful for working with blazor. |
GitHub repositories
This package is not used by any popular GitHub repositories.