phasTrak.AutoRegister
2.0.4
dotnet add package phasTrak.AutoRegister --version 2.0.4
NuGet\Install-Package phasTrak.AutoRegister -Version 2.0.4
<PackageReference Include="phasTrak.AutoRegister" Version="2.0.4" />
<PackageVersion Include="phasTrak.AutoRegister" Version="2.0.4" />
<PackageReference Include="phasTrak.AutoRegister" />
paket add phasTrak.AutoRegister --version 2.0.4
#r "nuget: phasTrak.AutoRegister, 2.0.4"
#:package phasTrak.AutoRegister@2.0.4
#addin nuget:?package=phasTrak.AutoRegister&version=2.0.4
#tool nuget:?package=phasTrak.AutoRegister&version=2.0.4
AutoRegister
AutoRegister is a C# source generator that will automatically create Microsoft.Extensions.DependencyInjection registrations for types marked with attributes.
This source generator is a fork of AutoRegisterInject by @patrickklaeren. This fork provides support for a variety of usages that are not supported by ARI since it is highly opinionated. This fork attempts to be non-opinionated in order to provide an actually useful product in most scenarios.
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:
namespace MyProject;
[RegisterScoped]
public class Foo { }
will automatically generate an extension method called AutoRegister()
for IServiceProvider
, that registers Foo
, as scoped.
internal IServiceCollection AutoRegister(this IServiceCollection serviceCollection)
{
serviceCollection.AddScoped<Foo>();
return serviceCollection;
}
In larger projects, dependency injection registration becomes tedious and in team situations can lead to merge conflicts which can be easily avoided.
AutoRegister 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 package, and start decorating classes with AutoRegister attributes.
Use dotnet add package phasTrak.AutoRegister
or add a package reference manually:
You can additionally mark the package as PrivateAssets="all"
and ExcludeAssets="runtime"
.
Setting PrivateAssets="all"
means any projects referencing this one will not also get a reference to the AutoRegister package. Setting ExcludeAssets="runtime"
ensures the AutoRegister.Attributes.dll file is not copied to your build output (it is not required at runtime).
<PackageReference Include="phasTrak.AutoRegister"
ExcludeAssets="runtime"
PrivateAssets="all" />
Usage
Classes should be decorated with one of four attributes:
[RegisterScoped]
[RegisterSingleton]
[RegisterTransient]
[RegisterHostedService]
Vants 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:
[RegisterScoped]
class Foo;
and get the following output:
serviceCollection.AddScoped<Foo>();
Update the service collection by invoking:
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:
[RegisterHostedService]
class Foo;
and get:
serviceCollection.AddHostedService<Foo>();
Register as interface
Implement one or many interfaces on your target class:
[RegisterTransient]
class Bar : IBar;
and get the following output:
serviceCollection.AddTransient<IBar, Bar>();
Implementing multiple interfaces will have the implementing type be registered for each distinct interface.
[RegisterTransient]
class Bar : IBar, IFoo, IBaz;
will output the following:
serviceCollection.AddTransient<IBar, Bar>();
serviceCollection.AddTransient<IFoo, Bar>();
serviceCollection.AddTransient<IBaz, Bar>();
If the target class implements an interface, it will only be registered with the implemented interfaces (IBar
).
If the class should be resolved as Bar
instead of by the interface, make use of the ExcludeTypes option:
[RegisterTransient(ExcludeTypes = [typeof(IBar), typeof(IFoo), typeof(IBaz)])]
Multiple assemblies
In addition to the AutoRegister
extension method, for every assembly that AutoRegister 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:
var serviceCollection = new ServiceCollection();
serviceCollection.AutoRegisterFromMyProjectMain();
serviceCollection.AutoRegisterFromMyProjectServices();
serviceCollection.AutoRegisterFromMyProjectData();
serviceCollection.BuildServiceProvider();
AutoRegister will remove illegal characters from assembly names in order to generate legal C# method names. ,
, .
and
will be removed.
If the resulting extension method name conflicts with another assembly, you can supply an assembly-level attribute to override the extension method name for that assembly.
[assembly: AutoRegisterAssemblyName("MyProjectDataServices")]
This will rename the extension with the provided assembly name override:
serviceCollection.AutoRegisterFromMyProjectDataServices();
Namespace
The AutoRegister
extension methods will be generated in the namespace of the decorated classes by default. This can be modified using an assembly-level attribute to override the namespace for that assembly/
[assembly: AutoRegisterNamespace("MyProject.Data.Services")]
Ignoring interfaces
By default AutoRegister 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 AutoRegister to explicitly register with only declared interfaces in the given attributes:
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:
serviceCollection.AddTransient<IBar, Foo>();
IFoo
will be ignored entirely.
Where you want to register as multiple interfaces, you can pass multiple types.
[RegisterScoped(typeof(IBar), typeof(IFoo))]
public class Foo;
You can also set specific interfaces to exclude from being registered with the ExcludeTypes option:
[RegisterScoped(ExcludeTypes = [typeof(IFoo)])]
public class Foo;
This works for all applicable attributes.
License
AutoRegister is MIT licensed. Do with it what you please under the terms of MIT.
Portions of this code are licensed under the MIT License from @BlackWhiteYoshi/AutoInterface. Copyright for portions of AutoRegister are held by Patrick Klaeren, 2024 as part of AutoRegisterInject. All other copyright for AutoRegister are held by phasTrak, 2024.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. 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. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.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 was computed. |
.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. |
This package has no dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.