Simple, lightweight & useful Dependency Injector for dotnet. |
-
Install Nuget package from here.
-
Go 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 can find your namespace from any assembly. You don't need to send any Assembly parameter.
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.
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>();
});
[InjectService] public IBookRepository BookRepository { get; set; }
[InjectService] public IBookRepository bookRepository;
DotNurse meets your custom requirements such as a defining lifetime, injecting into different interfaces etc.
.Nurse provides fluent api to manage your injections from single point.
services.AddServicesFrom("MyCompany.ProjectName.Services", ServiceLifetime.Scoped);
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"));
});
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");
});
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);
});
You may want to use directly objects sometimes, if an abstraction has multiple implmentations. Then you can use AddWithoutInterfaceToo
options as true.
If you set this option as true, object will be added into services without interface too, like following:
services.AddServicesFrom("ProjectNamespace.Services", ServiceLifetime.Scoped, opts =>
{
opts.AddWithoutInterfaceToo = true;
});
This makes something like following:
services.AddScoped<IBookService, BookService>();
services.AddScoped<BookService>(); // < -- Adds without interface too.
services.AddScoped<IAuthorService, AuthorService>();
services.AddScoped<AuthorService>(); // <-- Also for each pattern matched objects.
//...
You can manage your injections for class by class.
[ServiceLifeTime(ServiceLifetime.Singleton)] // <-- Only this object will be Singleton.
public class MyRepository : IMyRepository
{
// ...
}
You can ignore some of your class from injector.
[IgnoreInjection] // <-- This object will not be added to services
public class MyRepository : IMyRepository
{
// ...
}
You can manage your service types to add into. This attribute can be used multiple time 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>();