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                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="X39.Util.DependencyInjection" Version="2.0.1.8" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add X39.Util.DependencyInjection --version 2.0.1.8                
#r "nuget: X39.Util.DependencyInjection, 2.0.1.8"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.

Version Downloads Last updated
2.0.1.8 160 7/5/2024
2.0.1.7 141 2/28/2024
2.0.1.6 97 2/28/2024
2.0.1.5 120 2/28/2024
2.0.0.4 448 2/5/2023
2.0.0.3 283 1/21/2023
1.0.0.2 516 12/26/2022