DotNurseInjector
DotNurseInjector copied to clipboard
Simple, lightweight & useful Dependency Injector for dotnet.
DotNurseInjector
![]() |
.Nurse InjectorSimple, lightweight & useful Dependency Injector for dotnet. |
Getting Started
-
Install Nuget package from here.
-
Go to your Startup.cs, remove all your manual injections and use
AddServicesFrom()
method with namespace.- If you have following pattern:
- services.AddTransient<IBookRepository, BookRepository>(); - services.AddTransient<IAuthorRepository, AuthorRepository>(); - services.AddTransient<IPublisherRepository, PublisherRepository>();
- Replace them with following:
services.AddServicesFrom("MyCompany.ProjectName.Repositories.Concrete"); // <-- Your implementations namespace.
-
✅ That's it! DotNurse will scan your entire assembly and referenced assemblies to find types with the given namespace then register them to ServiceCollection.
Managing in Objects
You can even define lifetimes and expose types from objects via using [RegisterAs] attribute.
- Firstly, you should add following method for registering by attributes.
services.AddServicesByAttributes();
- Then you're ready to decorate your objects with
[RegisterAs]
attribute.[RegisterAs(typeof(IBookRepository))] public class BookRepository : IBookRepository, IAnotherInterface, IYetAnothetInterface { }
Property/Field Injection
This section is optional. You can still use default Microsoft Dependency Injection and skip this step.
You can use attribute injection instead of constructor injection. Using [InjectService]
attribute for properties or fields is enough to inject them from IoC.
Setting Up
You must replace your Service Provider with .Nurse Injecor to use Attribute Injection.
- Go your Program.cs and add
UseDotNurseInjector()
method to IHostBuilder.
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseDotNurseInjector() // <-- Adding this one is enough!
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
Usage
[InjectService] public IBookRepository BookRepository { get; private set; }
[InjectService] protected IBookRepository bookRepository;
Refactor your old codes
You can remove long constructor and place attribute to your fields or properties.
- Old code before DotNurseInjector
public class BookService
{
public IBookRepository BookRepository { get; private set; }
private readonly BookManager _bookManager;
// ...
public BookService(
IBookRepository bookRepository,
BookManager bookManager,
// ...
)
{
BookRepository = bookRepository;
_bookManager = bookManager;
// ...
}
}
- New code after DotNutseInjector
public class BookService
{
[InjectService] private IBookRepository BookRepository { get; private set; }
[InjectService] private readonly BookManager _bookManager;
// ...
}

Customizations
DotNurse meets your custom requirements such as defining lifetime, injecting into different interfaces, etc.
Managing from Startup
.Nurse provides fluent API to manage your injections from a single point.
Service Lifetime
services.AddServicesFrom("MyCompany.ProjectName.Services", ServiceLifetime.Scoped);
Interface Selector
You can define a pattern to choose interface from multiple interfaces.
services.AddServicesFrom("ProjectNamespace.Services", ServiceLifetime.Scoped, opts =>
{
opts.SelectInterface = interfaces => interfaces.FirstOrDefault(x => x.Name.EndsWith("Repository"));
});
Implementation Selector
You can define a pattern to choose which objects will be injected into IoC. For example you have a base type in same namespace and you don't want to add it into service collection. You can use this feature:
- ProjectNamespace.Services
- BookService
- ~~BaseService~~ <- You want to ignore this
- AuthorService
- ...
services.AddServicesFrom("ProjectNamespace.Services", ServiceLifetime.Scoped, opts =>
{
opts.SelectImplementtion = i => !i.Name.StartsWith("Base");
});
Implementation Base
Think about same scenario like previous, you can choose a base type to inject all classes which is inhetired from.
services.AddServicesFrom("ProjectNamespace.Services", ServiceLifetime.Scoped, opts =>
{
opts.ImplementationBase = typeof(BaseRepository);
});
Custom Registration Rule
You can use lambda expression to define your custom rules for registration.
In example, you can use it for registering types in a namespace recursively.
// Following code will register all types under Services namespace and sub-namespaces too.
services.AddServicesFrom(
x => x.Namespace != null && (x.Namespace.StartsWith("MyProject.Services"));
Managing from Objects
You can manage your injections for class by class.
Service Lifetime Attribute
[ServiceLifeTime(ServiceLifetime.Singleton)] // <-- Only this object will be Singleton.
public class MyRepository : IMyRepository
{
// ...
}
Ignoring Registration by Attribute
You can ignore some of your class from injector.
[DontRegister] // <-- This object will not be added into services
public class MyRepository : IMyRepository
{
// ...
}
Register As Attribute
You can manage your service types to add into. This attribute can be used multiple times at once.
/*
* Following object will be added into given types.
*/
[RegisterAs(typeof(IBookRepository))]
[RegisterAs(typeof(IBaseRepository<Book>), ServiceLifetime.Scoped)]
[RegisterAs(typeof(BookRepository), ServiceLifetime.Singleton)]
public class BookRepository : IBookRepository
{
// ...
}
This injection will do following code:
services.AddTransient<IBookRepository, BookRepository>();
services.AddScoped<IBaseRepository<Book>>, BookRepository>();
services.AddSingleton<BookRepository>();