Skip to content

Commit 2666132

Browse files
committed
Version 2.2.0
1 parent e32811f commit 2666132

File tree

9 files changed

+98
-90
lines changed

9 files changed

+98
-90
lines changed

NetCore.AutoRegisterDi/AutoRegisterData.cs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,6 @@ internal AutoRegisterData(IServiceCollection services, IEnumerable<Type> typesTo
3636
/// </summary>
3737
public IEnumerable<Type> TypesToConsider { get; }
3838

39-
/// <summary>
40-
///
41-
/// </summary>
42-
internal List<Type> InterfacesToIgnore { get; set; }
43-
= new List<Type>
44-
{
45-
typeof(IDisposable),
46-
typeof(ISerializable),
47-
typeof(IEquatable<>) //added for records
48-
};
49-
50-
5139
internal List<Type> FullyDefinedInterfacesToIgnore { get; set; }
5240
= new List<Type>
5341
{

NetCore.AutoRegisterDi/AutoRegisterHelpers.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ public static AutoRegisterData IgnoreThisInterface<TInterface>(this AutoRegister
6868
}
6969

7070
/// <summary>
71-
/// This allows you to state that the given interface will not be registered against a class.
72-
/// Useful if a class has an interface that you don't want registered against a class.
71+
/// This allows you to state that the given generic interface will not be registered against a class.
7372
/// This method handles generic interface where the inner generic type arguments aren't defined, which will stop all interfaces
74-
/// that uses the main type, e.g. IList{} would stop IList{int}, IList{string}, IList{AnotherClass}, etc.
73+
/// This version is here so that you can stop a record's IEquatable{} being added to the DI service,
74+
/// but it works for any generic interface.
7575
/// </summary>
7676
/// <param name="autoRegData"></param>
7777
/// <param name="interfaceType"></param>

NetCore.AutoRegisterDi/NetCore.AutoRegisterDi.csproj

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
6-
<PackageVersion>2.1.0</PackageVersion>
7-
<Version>2.1.0</Version>
8-
<AssemblyVersion>2.1.0.0</AssemblyVersion>
9-
<FileVersion>2.1.0.0</FileVersion>
6+
<PackageVersion>2.2.0</PackageVersion>
7+
<Version>2.2.0</Version>
8+
<AssemblyVersion>2.2.0.0</AssemblyVersion>
9+
<FileVersion>2.2.0.0</FileVersion>
1010
<PackageId>NetCore.AutoRegisterDi</PackageId>
1111
<PackageProjectUrl>https://github.com/JonPSmith/NetCore.AutoRegisterDi</PackageProjectUrl>
1212
<PackageLicenseUrl>https://raw.githubusercontent.com/JonPSmith/NetCore.AutoRegisterDi/master/LICENCE.txt</PackageLicenseUrl>
@@ -18,11 +18,8 @@
1818
<Company>Selective Analytics</Company>
1919
<Description>Extension method to find/register classes in an assembly into Microsoft.Extensions.DependencyInjection</Description>
2020
<PackageReleaseNotes>
21-
- New feature: IgnoreThisInterface method adds a interface to its interface ignore list.
22-
- Improvement: Added ISerializable interface to the default interface ignore list (IDisposable is already in base ignore list)
23-
- Improvement: You can use muliple have Where methods to filter out classes
24-
- Improvement: Returns a list of the classes/interfaces registered with the DI provider (useful for debugging)
25-
</PackageReleaseNotes>
21+
- New Feature: Method to ignore generic interfaces. Useful if you use record types and don't want to add its IEquatable to the DI
22+
</PackageReleaseNotes>
2623
<PackageIconUrl>https://raw.githubusercontent.com/JonPSmith/NetCore.AutoRegisterDi/master/AutoRegisterDiIcon128.png</PackageIconUrl>
2724
</PropertyGroup>
2825

@@ -35,7 +32,7 @@
3532
</PropertyGroup>
3633

3734
<ItemGroup>
38-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.0" />
35+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
3936
</ItemGroup>
4037

4138
</Project>

READMe.md

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# NetCore.AutoRegisterDi
22

3-
I have written a simple version of AutoFac's `RegisterAssemblyTypes` method that works directly with Microsoft's DI provider, i.e this library to scan an assemby (or assemblies) on your application and register all the public normal classes (i.e not [generic classes](https://www.tutorialspoint.com/Generics-vs-non-generics-in-Chash)) that have an interface into the Microsoft NET's [Dependency injection provider]https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection) (DI for short).
3+
I have written a simple version of AutoFac's `RegisterAssemblyTypes` method that works directly with Microsoft's DI provider, i.e this library to scan an assemby (or assemblies) on your application and register all the public normal classes (i.e not [generic classes](https://www.tutorialspoint.com/Generics-vs-non-generics-in-Chash)) that have an interface into the Microsoft NET's [Dependency injection provider]https://learn.microsoft.com/en-us/dotnet/core/extensions/dependency-injection (DI for short).
44

55
The NetCore.AutoRegisterDi is available on [NuGet as EfCore.SchemaCompare](https://www.nuget.org/packages/NetCore.AutoRegisterDi) and is an open-source library under the MIT license. See [ReleaseNotes](https://github.com/JonPSmith/NetCore.AutoRegisterDi/blob/masterReleaseNotes.md) for details of changes and information for each release.
66

@@ -10,15 +10,15 @@ There are two reasons:
1010

1111
1. I really hate having to hand-code each registering of my services - this extension method scans assembles and finds/registers classes with interfaces for you.
1212
2. I used to use [AutoFac's](https://autofac.org/) [assembly scanning](http://autofac.readthedocs.io/en/latest/register/scanning.html#assembly-scanning)
13-
feature, but I then saw a [tweet by @davidfowl](https://twitter.com/davidfowl/status/987866910946615296) about [Dependency Injection container benchmark (https://ipjohnson.github.io/DotNet.DependencyInjectionBenchmarks/) which showed the Microsoft's DI provider was much faster than AutoFac. I therefore implemented a similar (but not exactly the same) feature for the Microsoft.Extensions.DependencyInjection library.
13+
feature, but I then saw a [tweet by @davidfowl](https://twitter.com/davidfowl/status/987866910946615296) about [Dependency Injection container benchmark](https://ipjohnson.github.io/DotNet.DependencyInjectionBenchmarks/) which showed the Microsoft's DI provider was much faster than AutoFac. I therefore implemented a similar (but not exactly the same) feature for the `Microsoft.Extensions.DependencyInjection` library.
1414

15-
## Documentation
15+
# Documentation
1616

1717
_NOTE: There is an [article about this library](https://www.thereformedprogrammer.net/asp-net-core-fast-and-automatic-dependency-injection-setup/) which gives you an overview of this library. Useful if you haven't used this library before._
1818

19-
### Two, simple examples
19+
## Two, simple examples
2020

21-
#### Example 1 - scan the calling assembly
21+
### Example 1 - scan the calling assembly
2222

2323
This example scans the assembly where you call the AutoRegisterDi's `RegisterAssemblyPublicNonGenericClasses` method for all the classes which has one or more public interfaces and the Class's name ends with "Service" are registered with .NET's
2424

@@ -32,7 +32,7 @@ public void ConfigureServices(IServiceCollection services)
3232
.AsPublicImplementedInterfaces();
3333
```
3434

35-
#### Example 2 - scanning multiple assemblies
35+
### Example 2 - scanning multiple assemblies
3636

3737
This example scans the three assemblies and registers *all* the classes that have one or more public interfaces. That's because I have commented out the `.Where(c => c.Name.EndsWith("Service"))` method.
3838

@@ -54,22 +54,24 @@ public void ConfigureServices(IServiceCollection services)
5454
.AsPublicImplementedInterfaces();
5555
```
5656

57-
### Detailed information
57+
## Detailed information
5858

5959
There are four parts:
6060

61-
1. `RegisterAssemblyPublicNonGenericClasses`, which finds all the public classes that:
61+
1. `RegisterAssemblyPublicNonGenericClasses`, which finds all the public classes that:
6262
- Aren't abstract
6363
- Aren't a generic type, e.g. MyClass\<AnotherClass\>
6464
- Isn't nested. e.g. It won't look at classes defined inside other classes
6565
2. An optional `Where` method, which allows you to filter the classes to be considered.
6666
3. The `AsPublicImplementedInterfaces` method which finds ant interfaces on a class and registers those interfaces as pointing to the class.
67-
4. Various attributes that you can add to your classes to tell `NetCore.AutoRegisterDi` what to do:
68-
i) Set the `ServiceLifetime` of your class, e.g. `[RegisterAsSingleton]` to apply a `Singleton` lifetime to your class.
69-
ii) A `[DoNotAutoRegister]` attribute to stop library your class from being registered with the DI.
67+
4. There are two methods to allow you to say that a specific interface should be ignored:
68+
- The `IgnoreThisInterface<TInterface>()` method to add an interface to the the ignored list.
69+
- The `IgnoreThisGenericInterface(Type interfaceType)` method to add an generic interface to the the ignored list.
70+
5. Various attributes that you can add to your classes to tell `NetCore.AutoRegisterDi` what to do:
71+
- Set the `ServiceLifetime` of your class, e.g. `[RegisterAsSingleton]` to apply a `Singleton` lifetime to your class.
72+
- A `[DoNotAutoRegister]` attribute to stop library your class from being registered with the DI.
7073

71-
72-
#### 1. The `RegisterAssemblyPublicNonGenericClasses` method
74+
### 1. The `RegisterAssemblyPublicNonGenericClasses` method
7375

7476
The `RegisterAssemblyPublicNonGenericClasses` method will find all the classes in
7577

@@ -83,36 +85,65 @@ I only consider classes which match ALL of the criteria below:
8385
- Not Generic, e.g. MyClass\<T\>
8486
- Not Abstract
8587

86-
#### 2. The `Where` method
88+
### 2. The `Where` method
8789

88-
Pretty straightforward - you are provided with the `Type` of each class and you can filter by any of the `Type` properties etc. This allows you to do things like only registering certain classes, e.g `Where(c => c.Name.EndsWith("Service"))`
90+
Pretty straightforward - you are provided with the `Type` of each class and you can filter by any of the `Type` properties etc. This allows you to do things like only registering certain classes, e.g `Where(c => c.Name.EndsWith("Service"))`.
8991

9092
*NOTE: Useful also if you want to register some classes with a different time scope - See next section.*
9193

92-
#### 3. The `AsPublicImplementedInterfaces` method
94+
### 3. The `AsPublicImplementedInterfaces` method
9395

94-
The `AsPublicImplementedInterfaces` method finds any public, non-nested interfaces
95-
(apart from `IDisposable`) that each class implements and registers each
96-
interface, known as *service type*, against the class, known as the *implementation type*.
97-
This means if you use an interface in a constructor (or other DI-enabled places)
98-
then the Microsoft DI resolver will provide an instance of the class that interface
99-
was linked to.
100-
*See [Microsoft DI Docs](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1) for more on this*.*
96+
The `AsPublicImplementedInterfaces` method finds any public, non-nested interfaces (apart from `IDisposable` and `ISerializable`) that each class implements and registers each interface, known as _service type_, against the class, known as the _implementation type_. This means if you use an interface in a constructor (or other DI-enabled places) then the Microsoft DI resolver will provide an instance of the class that interface was linked to. _See [Microsoft DI Docs](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.1) for more on this_.
10197
102-
By default it will register the classes as having a lifetime of `ServiceLifetime.Transient`,
103-
but there is a parameter that allows you to override that.
98+
By default it will register the classes as having a lifetime of `ServiceLifetime.Transient`, but the `AsPublicImplementedInterfaces` method has an optional parameter called `lifetime` which you can change to another lifetime. Note that all the classes will have the same lifetime, but you can use AutoRegisterDi's attributes to set different lifetime to a class (see section 5).
10499

105100
*See this [useful article](https://joonasw.net/view/aspnet-core-di-deep-dive)
106101
on what lifetime (and other terms) means.*
107102

108-
#### 4. The attributes
103+
### 4. Ignore Interfaces
104+
105+
Some classes have interfaces that we don't really want to be registered to the DI provider - for instance `IDisposable` and `ISerializable`. Therefore AutoRegisterDi has two methods which allow you to define a interface that shouldn't be registered on any classes. They are:
106+
107+
#### The `IgnoreThisInterface<TInterface>` method
108+
109+
This method allows you to add a interface to to a list of interfaces that you don't register to the DI provider. The example below adds the `IMyInterface` in the list of interfaces to not register.
110+
111+
```c#
112+
service.RegisterAssemblyPublicNonGenericClasses()
113+
.IgnoreThisInterface<IMyInterface>()
114+
.AsPublicImplementedInterfaces();
115+
```
116+
117+
NOTES
118+
119+
- The list of interfaces to ignore has already got the `IDisposable` and `ISerializable` interfaces.
120+
- You can ignore many interfaces by including have many `IgnoreThisInterface<TInterface>` calls in the setup.
121+
122+
#### The `IgnoreThisGenericInterface(Type interfaceType)` method
123+
124+
This method was asked for Lajos Marton (GitHub @martonx). He was using [`record`s](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record) and found that each `record` has a `IEquatable<RecordType>` and he didn't wanted the DI provider be up with interfaces that aren't used.
125+
126+
You could use the `IgnoreThisInterface<IEquatable<RecordType>>`, but you would need to do that for every record. The other solution is to say that ALL `IEquatable<T>` are ignored. The code below will do that.
127+
128+
```c#
129+
service.RegisterAssemblyPublicNonGenericClasses()
130+
.IgnoreThisGenericInterface(typeof(IEquatable<>))
131+
.AsPublicImplementedInterfaces();
132+
```
133+
134+
NOTES:
135+
136+
- I haven't `IEquatable<>` to the ignore interface list as there may be a valid use to register a `IEquatable<SomeClass>` sometimes. In that case you would need to use `IgnoreThisGenericInterface` to define all your `record`s separably.
137+
- The method works for any generic interface type as long that the generic interface has no arguments are filled in, e.g `IDictionary<,>` is fine, but `IDictionary<,string>` won't work (you get an exception).
138+
139+
### 5. The attributes
109140

110-
Fedor Zhekov, (GitHub @ZFi88) added attributes to allow you to define the `ServiceLifetime` of your class, and also exclude your class from being registered with the DI.
141+
Fedor Zhekov, (GitHub @ZFi88) added attributes to allow you to define the `ServiceLifetime` of your class, and also exclude your class from being registered with the DI.
111142

112143
Here are the attributes that sets the `ServiceLifetime` to be used when `NetCore.AutoRegisterDi` registers your class with the DI.
113144

114145
1. `[RegisterAsSingleton]` - Singleton lifetime.
115146
2. `[RegisterAsTransient]` - Transient lifetime.
116147
3. `[RegisterAsScoped]` - Scoped lifetime.
117148

118-
The last attribute is `[DoNotAutoRegister]`, which stops `NetCore.AutoRegisterDi` registered that class with the DI.
149+
The last attribute is `[DoNotAutoRegister]`, which stops `NetCore.AutoRegisterDi` registered that class with the DI.

ReleaseNotes.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Release notes
22

3+
NOTE TO SELF: The Test project didn't compile when in Release mode (but works in Debug). I unloaded the Test project to build the NuGet
4+
5+
## 2.2.0
6+
7+
- New Feature: Method to ignore generic interfaces. Useful if you use record types and don't want to add its IEquatable<> to the DI
8+
39
## 2.1.0
410

511
- New feature: IgnoreThisInterface method adds a interface to its interface ignore list.

Test/Test.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netcoreapp2.1</TargetFramework>
4+
<TargetFramework>.NETCoreApp,Version=v2.1</TargetFramework>
55

66
<IsPackable>false</IsPackable>
77
</PropertyGroup>
88

99
<ItemGroup>
1010
<PackageReference Include="JetBrains.DotMemoryUnit" Version="3.1.20200127.214830" />
11-
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.0" />
11+
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.1" />
1212
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
1313
<PackageReference Include="xunit" Version="2.3.1" />
1414
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />

0 commit comments

Comments
 (0)