Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/patrickklaeren/AutoRegisterInject
C# Source Generator to automatically register dependencies in Microsoft Dependency Injection Service Collection
https://github.com/patrickklaeren/AutoRegisterInject
csharp dependency-injection microsoft source-generator
Last synced: 3 months ago
JSON representation
C# Source Generator to automatically register dependencies in Microsoft Dependency Injection Service Collection
- Host: GitHub
- URL: https://github.com/patrickklaeren/AutoRegisterInject
- Owner: patrickklaeren
- License: mit
- Created: 2022-12-10T17:49:20.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-06-18T07:45:47.000Z (5 months ago)
- Last Synced: 2024-07-30T22:17:44.779Z (3 months ago)
- Topics: csharp, dependency-injection, microsoft, source-generator
- Language: C#
- Homepage:
- Size: 89.8 KB
- Stars: 66
- Watchers: 2
- Forks: 5
- Open Issues: 4
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
- RSCG_Examples - https://github.com/patrickklaeren/AutoRegisterInject
- csharp-source-generators - AutoRegisterInject - ![stars](https://img.shields.io/github/stars/patrickklaeren/AutoRegisterInject?style=flat-square&cacheSeconds=604800) ![last commit](https://img.shields.io/github/last-commit/patrickklaeren/AutoRegisterInject?style=flat-square&cacheSeconds=86400) Automatically generate Microsoft Dependency Injection ServiceCollection registrations for your classes from attributes. (Source Generators / Dependency Injection (IoC Container))
README
# AutoRegisterInject
AutoRegisterInject, also referred to as ARI, is a C# source generator that will automatically create Microsoft.Extensions.DependencyInjection registrations for types marked with attributes.
This is a compile time alternative to reflection/assembly scanning for your injections or manually adding to the `ServiceCollection` every time a new type needs to be registered.
For example:
```cs
namespace MyProject;[RegisterScoped]
public class Foo { }
```will automatically generate an extension method called `AutoRegister()` for `IServiceProvider`, that registers `Foo`, as scoped.
```cs
internal IServiceCollection AutoRegister(this IServiceCollection serviceCollection)
{
serviceCollection.AddScoped();
return serviceCollection;
}
```In larger projects, dependency injection registration becomes tedious and in team situations can lead to merge conflicts which can be easily avoided.
AutoRegisterInject moves the responsibility of service registration to the owning type rather than external service collection configuration, giving control and oversight of the type that is going to be registered with the container.
## Installation
Install the [Nuget](https://www.nuget.org/packages/AutoRegisterInject) package, and start decorating classes with ARI attributes.
Use `dotnet add package AutoRegisterInject` or add a package reference manually:
```xml
```
## Usage
Classes should be decorated with one of four attributes:
- `[RegisterScoped]`
- `[RegisterSingleton]`
- `[RegisterTransient]`
- `[RegisterHostedService]`Variants for keyed and the service `Try` register pattern are also available:
- `[TryRegisterScoped]`
- `[TryRegisterSingleton]`
- `[TryRegisterTransient]`
- `[RegisterKeyedScoped]`
- `[RegisterKeyedSingleton]`
- `[RegisterKeyedTransient]`Each keyed attribute has a `Try` counterpart.
Register a class:
```cs
[RegisterScoped]
class Foo;
```and get the following output:
```cs
serviceCollection.AddScoped();
```Update the service collection by invoking:
```cs
var serviceCollection = new ServiceCollection();
serviceCollection.AutoRegister();
serviceCollection.BuildServiceProvider();
```You can now inject `Foo` as a dependency and have this resolved as scoped.
Alternatively, you can register hosted services by:
```cs
[RegisterHostedService]
class Foo;
```and get:
```cs
serviceCollection.AddHostedService();
```### Register as interface
Implement one or many interfaces on your target class:
```cs
[RegisterTransient]
class Bar : IBar;
```and get the following output:
```cs
serviceCollection.AddTransient();
```**Important note:** AutoRegisterInject is opinionated and `Bar` will only be registered with its implemented interface. ARI will **not** register `Bar`. `Bar` will always need to be resolved from `IBar` in your code.
Implementing multiple interfaces will have the implementing type be registered for each distinct interface.
```cs
[RegisterTransient]
class Bar : IBar, IFoo, IBaz;
```will output the following:
```cs
serviceCollection.AddTransient();
serviceCollection.AddTransient();
serviceCollection.AddTransient();
```**Important note:** AutoRegisterInject is opinionated and `Bar` will only be registered with its implemented interfaces. ARI will **not** register `Bar`. `Bar` will always need to be resolved from `IBar`, `IFoo` or `IBaz` in your code.
### Multiple assemblies
In addition to the `AutoRegister` extension method, every assembly that AutoRegisterInject is a part of, a `AutoRegisterFromAssemblyName` will be generated. This allows you to configure your service collection from one, main, executing assembly.
Given 3 assemblies, `MyProject.Main`, `MyProject.Services`, `MyProject.Data`, you can configure the `ServiceCollection` as such:
```cs
var serviceCollection = new ServiceCollection();
serviceCollection.AutoRegisterFromMyProjectMain();
serviceCollection.AutoRegisterFromMyProjectServices();
serviceCollection.AutoRegisterFromMyProjectData();
serviceCollection.BuildServiceProvider();
```AutoRegisterInject will remove illegal characters from assembly names in order to generate legal C# method names. `,`, `.` and ` ` will be removed.
### Ignoring interfaces
By default ARI will register a type with all the interfaces it implements, however this excludes `System.IDisposable` and its `IAsyncDisposable` counterpart.
You can ignore interfaces by telling ARI to *explicitly* register with only declared interfaces in the given attributes:
```cs
public interface IFoo { }
public interface IBar { }
[RegisterScoped(typeof(IBar))]
public class Foo;
```this will result in `Foo` ONLY being registered as `IBar` and the following output:
```cs
serviceCollection.AddTransient();
````IFoo` will be ignored entirely.
Where you want to register as multiple interfaces, you can pass multiple types.
```cs
[RegisterScoped(typeof(IBar), typeof(IFoo))]
public class Foo;
```This works for all applicable attributes.
## License
AutoRegisterInject is MIT licensed. Do with it what you please under the terms of MIT.