Katalogo: for Microsoft Dependency injection what Module is to Autofac or Registry to Structuremap
Create a bundle of components for Microsoft.Extensions.DependencyInjection using Katalogo's Catalog class just like you would in Structuremap using Registry or Autofac using Module. Built in assembly scanning support as well.
The problem
If you are a user of Structuremap or Autofac (or other DI containers for that matter) you probably know the technique to create a class where you can wire up your container. In Structuremap it is called Registry while Autofac has got Module.
.Net core has got its own - be it simple - DI implementation called Microsoft Dependency Injection through the Microsoft.Extensions.DependencyInjection
It mainly operates in the Asp.net Core space but you can effectively use it anywhere.
However no technique like Registry or Module exists today. You can create an extension method on IServiceCollection and use that as a similar way to bundle a set of related components. And while this works this would mean you still need to do this explicitly when creating/configuring your ServiceCollection. The advantage that Registry or Module have is that those DI's also support assembly scanning. This would allow your DI to look for assemblies with classes that implement Registry or Module and register the components itself.
Meet Katalogo
Katalogo is a small library which is inspired by Scrutor library from Kristian Hellang. I used the assembly scanning feature from Scrutor as the base for Katalogo.
In Katalogo there is the Catalog class which provides a way to create your own bundle.
using Microsoft.Extensions.DependencyInjection;
namespace Katalogo
{
public abstract class Catalog
{
public IServiceCollection Services { get; }
protected Catalog(IServiceCollection services)
{
Services = services;
}
}
}
As you can see no rocket science here. You just create a new class and inherit from Catalog. In the constructor you'll get access to the IServiceCollection so you can create your own registrations.
public interface ITest
{
void Hello();
}
public class Test : ITest
{
public void Hello()
{
}
}
public class TestCatalog : Catalog
{
public TestCatalog(IServiceCollection services) : base(services)
{
services.AddTransient<ITest, Test>();
}
}
An advantage is that you can now make your implementations internal but still make it possible to register them in an other library in the ServiceCollection without exposing them if you don't want to.
Making it work
So when you are ready to wire up your services you can do that using the .Scan() method which is an extension for IServiceCollection. It will allow you to choose the scanning technique and then register all Catalog implementations found in the discovered assemblies.
var services = New ServiceCollection();
services.Scan(scanner => scanner.FromCallingAssembly().RegisterCatalogs()
The above code will look in the calling assembly for Catalog implementations and register them. Other scanning strategies are:
- FromExecutingAssembly: Will scan for types from the entry assembly.
- FromApplicationDependencies: Will load and scan all runtime libraries referenced by the currently executing application.
- FromDependencyContext: Will load and scan all runtime libraries in the given context
- FromAssemblyOf<T>(): Will scan for types from the assembly of type T
- FromAssembliesOf(paramsType[] types): Will scan for types from the assemblies of each type in types
- FromAssemblies(params Assembly[] assemblies): Will scan for types in each assembly in assemblies
Some of the methods above also have some overloads to steer the scanning a bit further. See the IAssemblySelector interface for more information.
Do we need to scan?
No.
You can register a catalog directly as well.
var services = new ServiceCollection();
services.RegisterCatalog<TestCatalog>();
This will register the Catalog without scanning for assemblies since you are specifying the type directly.
You can see all the source on Github: https://github.com/suddenelfilio/katalogo
Install it in your .net project using the Nuget package: https://www.nuget.org/packages/Katalogo
Let me know if you have any remarks or maybe feature requests via the Github issues: https://github.com/suddenelfilio/Katalogo/issues
I also accept Pull requests if you would like to extend it even further.