Skip to content

Service Registration

Alexander Stärk edited this page Sep 25, 2026 · 2 revisions

Service Registration

Lifetimes

Use one of the lifetime-specific attributes:

[RegisterServiceTransient]
public class MyTransientService { }

[RegisterServiceScoped]
public class MyScopedService { }

[RegisterServiceSingleton]
public class MySingletonService { }

Equivalent explicit form:

[RegisterService(RegistrationScope.Scoped)]
public class MyService { }

Registering as interface or base type

Use As when you want the service exposed as a specific type:

[RegisterServiceScoped(As = typeof(IMyService))]
public class MyService : IMyService { }

ImplementsITypeName

By default, ImplementsITypeName = true.

This means if a type MyService implements IMyService, that interface is considered automatically.

Disable it if you need strict explicit registration:

[RegisterServiceTransient(ImplementsITypeName = false)]
public class MyService : IMyService { }

Marker attributes on interfaces or base classes

You can put registration attributes on shared abstractions so all implementations inherit registration behavior.

This is useful for plugin-like or feature-module architectures.

Custom marker attributes (custom names + defaults)

You can introduce your own attribute names and predefined registration defaults.

Recommended pattern:

  • create a custom attribute type for your domain
  • implement IRegisterServiceAttribute
  • annotate that custom attribute type with one of the built-in registration attributes (RegisterServiceTransient, RegisterServiceScoped, RegisterServiceSingleton, or RegisterService)

Example:

using Basilisque.DependencyInjection.Registration.Annotations;

[RegisterServiceScoped(As = typeof(IMyDomainService), ImplementsITypeName = false)]
public sealed class RegisterDomainServiceAttribute : Attribute, IRegisterServiceAttribute
{
}

[RegisterDomainService]
public sealed class MyDomainService : IMyDomainService
{
}

This gives you:

  • a project-specific attribute name
  • reusable default registration behavior

Important note:

  • prefer the marker-attribute pattern above for defaults
  • do not rely on constructor-internal logic of a derived attribute to communicate defaults to the generator

Multiple registrations

The same implementation can be registered multiple times with different configuration:

[RegisterServiceScoped(ImplementsITypeName = false)]
[RegisterServiceSingleton(As = typeof(IMyContract), ImplementsITypeName = false)]
[RegisterServiceTransient]
public class MultiRegisteredService : IMyContract { }

Open generics

Open generic registrations are supported:

[RegisterServiceTransient(As = typeof(IRepository<>))]
public class Repository<T> : IRepository<T> { }

Next

Clone this wiki locally