DBaker.DepRegAttributes 8.0.0

dotnet add package DBaker.DepRegAttributes --version 8.0.0
NuGet\Install-Package DBaker.DepRegAttributes -Version 8.0.0
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="DBaker.DepRegAttributes" Version="8.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add DBaker.DepRegAttributes --version 8.0.0
#r "nuget: DBaker.DepRegAttributes, 8.0.0"
#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 DBaker.DepRegAttributes as a Cake Addin
#addin nuget:?package=DBaker.DepRegAttributes&version=8.0.0

// Install DBaker.DepRegAttributes as a Cake Tool
#tool nuget:?package=DBaker.DepRegAttributes&version=8.0.0

Add services to your Service Collection with attributes! Never touch your Program.cs file again!

There are three attributes you can use to register services with your ServiceCollection:

[RegisterTransient]
[RegisterScoped]
[RegisterSingleton]

There are also IServiceCollection extensions to add these services:

serviceCollection.AddByAttribute();
serviceCollection.AddByAttribute(assembly);

Passing an assembly will register services only from that assembly. If you don't pass an assembly, services from the current assembly will be registered

Basic Usage

[RegisterTransient]
public class ExampleService
{
    //Equivalent:
    //serviceCollection.AddTransient<ExampleService>();
}

If your service has an interface with a matching name, it will be automatically used. This is the most used case.

[RegisterTransient]
public class ExampleService : IExampleService
{
    //Equivalent:
    //serviceCollection.AddTransient<IExampleService, ExampleService>();
}

Note: this does not happen if you have any explicitly defined service types in the attribute

Registering with Explicit Service Types

[RegisterTransient<IAnotherExampleService>]
public class ExampleService : ExampleServiceBase, IExampleService, IAnotherExampleService
{
    //Equivalent:
    //serviceCollection.AddTransient<IAnotherExampleService, ExampleService>();
}

You can register your implementation with as many service types as you want.

[RegisterTransient<ExampleServiceBase, IExampleService, IAnotherExampleService>]
public class ExampleService : ExampleServiceBase, IExampleService, IAnotherExampleService
{
    //Equivalent:
    //serviceCollection.AddTransient<ExampleServiceBase, ExampleService>();
    //serviceCollection.AddTransient<IExampleService, ExampleService>();
    //serviceCollection.AddTransient<IAnotherExampleService, ExampleService>();
}

You can also use multiple attributes.

[RegisterTransient<ExampleServiceBase>]
[RegisterTransient<IExampleService>]
[RegisterTransient<IAnotherExampleService>]
public class ExampleService : ExampleServiceBase, IExampleService, IAnotherExampleService
{
    //Equivalent:
    //serviceCollection.AddTransient<ExampleServiceBase, ExampleService>();
    //serviceCollection.AddTransient<IExampleService, ExampleService>();
    //serviceCollection.AddTransient<IAnotherExampleService, ExampleService>();
}

If you are using a C# language version lower than 11, you will not be able to use generic arguments. Instead use type arguments:

[RegisterTransient(typeof(IExampleService), typeof(IAnotherExampleService))]
public class ExampleService : ExampleServiceBase, IExampleService, IAnotherExampleService
{
    //Equivalent:
    //serviceCollection.AddTransient<IExampleService, ExampleService>();
    //serviceCollection.AddTransient<IAnotherExampleService, ExampleService>();
}

When using multiple servcie types, scoped and singletons work a little differently form transient. For each attribute, only one object will be constructed for a singleton or scoped service.

[RegisterSingleton<IExampleService, IAnotherExampleService>]
public class ExampleService : IExampleService, IAnotherExampleService
{
    //Equivalent:
    //serviceCollection.AddSingleton<IExampleService, ExampleService>();
    //serviceCollection.AddSingleton(sp => (IAnotherExampleService)sp.GetRequiredService<IExampleService>());
}

As you can see, you will get a reference to the same object when requesting either service.

If you use multiple attributes you will get a different singleton for each service.

[RegisterSingleton<IExampleService>]
[RegisterSingleton<IAnotherExampleService>]
public class ExampleService : IExampleService, IAnotherExampleService
{
    //Equivalent:
    //serviceCollection.AddSingleton<IExampleService, ExampleService>();
    //serviceCollection.AddSingleton<IAnotherExampleService, ExampleService>();
}

Registration Tags

Tags can be used to register services conditionally when building your service collection.

Tags are objects, so you can use anything as long as it can be passed as an attribute argument. This limits them to constants (i.e. strings, enums, numbers).

serviceCollection.AddByAttribute("Example", 14, ExampleEnum.ExampleValue);

Untagged services will always be included, even when passing tags to the AddByAttribute function. Services are registered in the same order as their attributes, keep this in mind if you have a service that is registered as tagged and untagged. You will want the tagged attribute bellow the untagged attribute, since the untagged attribute will be included all the time.

Define tags via the Tag property on attributes:

[RegisterTransient(Tag = "Example")]
public class ExampleService
{
    //Equivalent:
    //if(includedTag.Equals("Example"))
    //{
    //    serviceCollection.AddTransient<ExampleService>();
    //}
}

If you are using tags and want to register services form a specific assembly, pass the assembly as the first argument:

serviceCollection.AddByAttribute(assembly, "Key1", "Key2");

Keyed Services

Note: This is not available in version 3.

You can read more about keyed services in the .NET 8 Release Notes.

To register a keyed service, pass a key to the Key property of any register attribute:

[RegisterTransient(Key = "Example")]
public class ExampleService
{
    //Equivalent:
    //serviceCollection.AddKeyedTransient<ExampleService>("Example");
}

Unbound Generics

You can register a generic class as an unbound generic:

[RegisterTransient]
public class ExampleService<T>
{
    //Equivalent:
    //serviceCollection.AddTransient(typeof(ExampleService<>));
}

Unbound generics do not automatically register matching interface types, so you will have to do it manually:

[RegisterTransient(typeof(IExampleService<>))]
public class ExampleService<T> : IExampleService<T>
{
    //Equivalent:
    //serviceCollection.AddTransient(typeof(IExampleService<>), typeof(ExampleService<>));
}

Note: You must use typeof() arguments when doing this, you cannot pass an unbound generic as a generic argument. Note 2: There is no analyzer support for unbound generics, failures will only appear at runtime.

Product 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. 
.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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
8.0.0 166 1/11/2024
6.0.0 201 10/27/2023
5.0.0 125 10/15/2023
4.0.0 166 9/26/2023
3.1.0 86 1/11/2024
3.0.0 424 11/15/2022
2.0.0 426 8/16/2022
1.0.0 480 2/5/2022