|
1 | 1 | # NetCore.AutoRegisterDi |
2 | 2 |
|
3 | | -This library contains |
| 3 | +This [NuGet library]() |
| 4 | +contains an extension method to scan an assemby and register all |
| 5 | +the public classes against their implemented interfaces(s) into the |
| 6 | +Microsoft.Extensions.DependencyInjection dependency injection provider. |
| 7 | + |
| 8 | +I have written a simple version of AutoFac's `RegisterAssemblyTypes` |
| 9 | +method that works directly with Microsoft's DI provider. |
| 10 | +Here is an example of me using this with ASP.NET Core |
| 11 | + |
| 12 | +```c# |
| 13 | +public void ConfigureServices(IServiceCollection services) |
| 14 | +{ |
| 15 | + //... other configure code removed |
| 16 | +
|
| 17 | + var assemblyToScan = Assembly.GetExecutingAssembly(); //..or whatever assembly you need |
| 18 | +
|
| 19 | + service.RegisterAssemblyPublicNonGenericClasses(assemblyToScan) |
| 20 | + .Where(c => c.Name.EndsWith("Service")) |
| 21 | + .AsPublicImplementedInterfaces(); |
| 22 | +``` |
| 23 | + |
| 24 | +## Wht have I written this extension? |
| 25 | + |
| 26 | +There are two reasons: |
| 27 | + |
| 28 | +1. I really hate having to hand-code each registering of the services - this |
| 29 | +extension method scans assembles and finds/registers classes with interfaces for you. |
| 30 | +2. I used to use [AutoFac's](https://autofac.org/) [assembly scanning](http://autofac.readthedocs.io/en/latest/register/scanning.html#assembly-scanning) |
| 31 | +feature, but I then saw a [tweet by @davidfowl](https://twitter.com/davidfowl/status/987866910946615296) about |
| 32 | +[Dependency Injection container benchmarks](https://ipjohnson.github.io/DotNet.DependencyInjectionBenchmarks/) |
| 33 | +which showed the Microsoft's DI provider was much faster than AutoFac. |
| 34 | +I therefore implemented a similar (but not exactly the same) feature for the |
| 35 | +Microsoft.Extensions.DependencyInjection library. |
| 36 | + |
| 37 | +### Detailed information |
| 38 | + |
| 39 | +There are three parts: |
| 40 | +1. `RegisterAssemblyPublicNonGenericClasses`, which finds all the classes. |
| 41 | +2. An options `Where` method, which allows you to filter the classes to be considered. |
| 42 | +3. The `AsPublicImplementedInterfaces` method which finds ant interfaces on a class and |
| 43 | +registers those interfaces as pointing to the class. |
| 44 | + |
| 45 | + |
| 46 | +#### 1. The `RegisterAssemblyPublicNonGenericClasses` method |
| 47 | + |
| 48 | +The `RegisterAssemblyPublicNonGenericClasses` method will find all the classes |
| 49 | +in the assembly that I referenced that are considered useful for registering. |
| 50 | +The exact criteria I use are: |
| 51 | + |
| 52 | +- Public access |
| 53 | +- Not nested, e.g. It won't look at classes defined inside other classes |
| 54 | +- Not Generic, e.g. MyClass<T> |
| 55 | +- Not Abstract |
| 56 | + |
| 57 | +It can take a list/array of assemblies to scan. Two typical wasy of providing an assembly are: |
| 58 | + |
| 59 | +- `Assembly.GetExecutingAssembly()`, which does what is says |
| 60 | +- `Assembly.GetAssembly(typeof(YourClass))`, which gets the assembly that `YourClass` was defined in. |
| 61 | + |
| 62 | +#### 2. The `Where` method |
| 63 | + |
| 64 | +Pretty straughtforward - you are provided with the `Type` of each class and |
| 65 | +you can filter by any of the `Type` properties etc. This allows you to |
| 66 | +do things like only registering certain classes, |
| 67 | +e.g `Where(c => c.Name.EndsWith("Service"))` |
| 68 | + |
| 69 | +*NOTE: Useful also if you want to register some classes with a different timetime scope.* |
| 70 | + |
| 71 | +#### 3. The `AsPublicImplementedInterfaces` method |
| 72 | + |
| 73 | +The `AsPublicImplementedInterfaces` method finds any public, non-nested interfaces |
| 74 | +(apart from `IDisposable`) that each class implements and registers each |
| 75 | +interface, known as *service type*, against the class, known as the *implementation type*. |
| 76 | + |
| 77 | +By default it will register the classes as having a lifetime of `ServiceLifetime.Transient`, |
| 78 | +but there is a parameter that allows you to override that. |
| 79 | + |
| 80 | +*See this [useful article](https://joonasw.net/view/aspnet-core-di-deep-dive) |
| 81 | +on what lifetime (and other terms) means.* |
0 commit comments