Skip to content

Commit 18a4724

Browse files
Merge pull request #472 from johelvisguzman/issue369
Added a new ninject ioc container extensions
2 parents d31e4b1 + 6a46da0 commit 18a4724

File tree

11 files changed

+343
-8
lines changed

11 files changed

+343
-8
lines changed

DotNetToolkit.Repository.sln

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 15
4-
VisualStudioVersion = 15.0.27004.2006
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.28803.352
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}"
77
EndProject
@@ -45,6 +45,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.In
4545
EndProject
4646
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolkit.Repository.Caching.Memcached", "src\DotNetToolkit.Repository.Caching.Memcached\DotNetToolkit.Repository.Caching.Memcached.csproj", "{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}"
4747
EndProject
48+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetToolkit.Repository.Extensions.Ninject", "src\DotNetToolkit.Repository.Extensions.Ninject\DotNetToolkit.Repository.Extensions.Ninject.csproj", "{BC5B405A-725D-47EC-8FE1-D420CFED8939}"
49+
EndProject
4850
Global
4951
GlobalSection(SolutionConfigurationPlatforms) = preSolution
5052
Debug|Any CPU = Debug|Any CPU
@@ -118,6 +120,10 @@ Global
118120
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}.Debug|Any CPU.Build.0 = Debug|Any CPU
119121
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}.Release|Any CPU.ActiveCfg = Release|Any CPU
120122
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96}.Release|Any CPU.Build.0 = Release|Any CPU
123+
{BC5B405A-725D-47EC-8FE1-D420CFED8939}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
124+
{BC5B405A-725D-47EC-8FE1-D420CFED8939}.Debug|Any CPU.Build.0 = Debug|Any CPU
125+
{BC5B405A-725D-47EC-8FE1-D420CFED8939}.Release|Any CPU.ActiveCfg = Release|Any CPU
126+
{BC5B405A-725D-47EC-8FE1-D420CFED8939}.Release|Any CPU.Build.0 = Release|Any CPU
121127
EndGlobalSection
122128
GlobalSection(SolutionProperties) = preSolution
123129
HideSolutionNode = FALSE
@@ -140,6 +146,7 @@ Global
140146
{445F6C84-FF28-4243-8148-DAB5A4813F93} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
141147
{C895B8F4-5083-4D97-A1E6-D7DF01BDBE9D} = {DAB3DD1E-AD99-46C9-AC42-07E2F03D5A06}
142148
{421F9CC1-9A5F-4F3D-A851-AB72958A4E96} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
149+
{BC5B405A-725D-47EC-8FE1-D420CFED8939} = {DD273D5E-6D6C-41FA-A0C8-646CC53C4DC3}
143150
EndGlobalSection
144151
GlobalSection(ExtensibilityGlobals) = postSolution
145152
SolutionGuid = {96973E0C-81D1-42DE-9F78-7103241B4E07}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ If you want to use DotNetToolkit.Repository for the first time, the [Getting Sta
2626
[DotNetToolkit.Repository.Xml](https://www.nuget.org/packages/DotNetToolkit.Repository.Xml/) | [![DotNetToolkit.Repository.Xml](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Xml.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Xml/) | [![DotNetToolkit.Repository.Xml](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Xml.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Xml/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Xml.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Xml) |
2727
[DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection/) | [![DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection/) | [![DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection) |
2828
[DotNetToolkit.Repository.Extensions.Unity](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Unity/) | [![DotNetToolkit.Repository.Extensions.Unity](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Extensions.Unity.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Unity/) | [![DotNetToolkit.Repository.Extensions.Unity](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Extensions.Unity.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Unity/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Extensions.Unity.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Extensions.Unity) |
29+
[DotNetToolkit.Repository.Extensions.Ninject](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Ninject/) | [![DotNetToolkit.Repository.Extensions.Ninject](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Extensions.Ninject.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Ninject/) | [![DotNetToolkit.Repository.Extensions.Ninject](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Extensions.Ninject.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Extensions.Ninject/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Extensions.Ninject.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Extensions.Ninject) |
2930
[DotNetToolkit.Repository.Caching.InMemory](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.InMemory/) | [![DotNetToolkit.Repository.Caching.InMemory](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Caching.InMemory.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.InMemory/) | [![DotNetToolkit.Repository.Caching.InMemory](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Caching.InMemory.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.InMemory/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Caching.InMemory.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Caching.InMemory) |
3031
[DotNetToolkit.Repository.Caching.Redis](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Redis/) | [![DotNetToolkit.Repository.Caching.Redis](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Caching.Redis.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Redis/) | [![DotNetToolkit.Repository.Caching.Redis](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Caching.Redis.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Redis/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Caching.Redis.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Caching.Redis) |
3132
[DotNetToolkit.Repository.Caching.Memcached](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Memcached/) | [![DotNetToolkit.Repository.Caching.Memcached](https://img.shields.io/nuget/v/DotNetToolkit.Repository.Caching.Memcached.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Memcached/) | [![DotNetToolkit.Repository.Caching.Memcached](https://img.shields.io/nuget/dt/DotNetToolkit.Repository.Caching.Memcached.svg)](https://www.nuget.org/packages/DotNetToolkit.Repository.Caching.Memcached/) | [![MyGet (dev)](https://img.shields.io/myget/dotnettoolkitrepositorydev/v/DotNetToolkit.Repository.Caching.Memcached.svg)](https://www.myget.org/feed/dotnettoolkitrepositorydev/package/nuget/DotNetToolkit.Repository.Caching.Memcached) |

appveyor.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ after_build:
6060
- dotnet pack .\src\DotNetToolkit.Repository.Xml\DotNetToolkit.Repository.Xml.csproj --configuration Release
6161
- dotnet pack .\src\DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection\DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection.csproj --configuration Release
6262
- dotnet pack .\src\DotNetToolkit.Repository.Extensions.Unity\DotNetToolkit.Repository.Extensions.Unity.csproj --configuration Release
63+
- dotnet pack .\src\DotNetToolkit.Repository.Extensions.Ninject\DotNetToolkit.Repository.Extensions.Ninject.csproj --configuration Release
6364
- dotnet pack .\src\DotNetToolkit.Repository.Caching.InMemory\DotNetToolkit.Repository.Caching.InMemory.csproj --configuration Release
6465
- dotnet pack .\src\DotNetToolkit.Repository.Caching.Redis\DotNetToolkit.Repository.Caching.Redis.csproj --configuration Release
6566
- dotnet pack .\src\DotNetToolkit.Repository.Caching.Memcached\DotNetToolkit.Repository.Caching.Memcached.csproj --configuration Release

src/DotNetToolkit.Repository.Extensions.Microsoft.DependencyInjection/ServiceCollectionExtensions.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static class ServiceCollectionExtensions
2626
/// <param name="assembliesToScan">The assemblies to scan.</param>
2727
/// <returns>The same instance of the service collection which has been configured with the repositories.</returns>
2828
/// <remarks>
29-
/// This method will scan for repositories and interceptors from the specified assemblies collection, and will register them to the service collection.
29+
/// This method will scan for repositories and interceptors from the specified assemblies collection, and will register them to the container.
3030
/// </remarks>
3131
public static IServiceCollection AddRepositories([NotNull] this IServiceCollection services, [NotNull] Action<RepositoryOptionsBuilder> optionsAction, [NotNull] params Assembly[] assembliesToScan)
3232
{
@@ -83,7 +83,8 @@ public static IServiceCollection AddRepositories([NotNull] this IServiceCollecti
8383
{
8484
var serviceType = t.Key;
8585
var implementationTypes = t.Where(x => x.IsGenericType == serviceType.IsGenericType &&
86-
x.GetGenericArguments().Length == serviceType.GetGenericArguments().Length);
86+
x.GetGenericArguments().Length == serviceType.GetGenericArguments().Length &&
87+
x.IsVisible && !x.IsAbstract);
8788

8889
foreach (var implementationType in implementationTypes)
8990
{
@@ -138,7 +139,7 @@ public static IServiceCollection AddRepositories([NotNull] this IServiceCollecti
138139
/// <returns>The same instance of the service collection which has been configured with the repositories.</returns>
139140
/// <remarks>
140141
/// This method will scan for repositories and interceptors from the assemblies that have been loaded into the
141-
/// execution context of this application domain, and will register them to the service collection.
142+
/// execution context of this application domain, and will register them to the container.
142143
/// </remarks>
143144
public static IServiceCollection AddRepositories([NotNull] this IServiceCollection services, [NotNull] Action<RepositoryOptionsBuilder> optionsAction)
144145
{
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Import Project="..\..\build\common.props" />
4+
5+
<PropertyGroup>
6+
<TargetFrameworks>net451;netstandard2.0</TargetFrameworks>
7+
<Description>Extensions for the Ninject DI container.</Description>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="Ninject" Version="3.3.4" />
12+
</ItemGroup>
13+
14+
<ItemGroup>
15+
<ProjectReference Include="..\DotNetToolkit.Repository\DotNetToolkit.Repository.csproj" />
16+
</ItemGroup>
17+
18+
</Project>
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
namespace DotNetToolkit.Repository.Extensions.Ninject
2+
{
3+
using Configuration.Interceptors;
4+
using Configuration.Options;
5+
using Configuration.Options.Internal;
6+
using Factories;
7+
using global::Ninject;
8+
using JetBrains.Annotations;
9+
using System;
10+
using System.Collections.Generic;
11+
using System.Linq;
12+
using System.Reflection;
13+
using Transactions;
14+
using Utility;
15+
16+
/// <summary>
17+
/// Contains various extension methods for <see cref="IKernel" />
18+
/// </summary>
19+
public static class KernelExtensions
20+
{
21+
/// <summary>
22+
/// Binds all the repositories services using the specified options builder.
23+
/// </summary>
24+
/// <param name="kernel">The kernel.</param>
25+
/// <param name="optionsAction">A builder action used to create or modify options for the repositories.</param>
26+
/// <param name="assembliesToScan">The assemblies to scan.</param>
27+
/// <remarks>
28+
/// This method will scan for repositories and interceptors from the specified assemblies collection, and will bind them to the container.
29+
/// </remarks>
30+
public static void BindRepositories([NotNull] this IKernel kernel, [NotNull] Action<RepositoryOptionsBuilder> optionsAction, [NotNull] params Assembly[] assembliesToScan)
31+
{
32+
Guard.NotNull(kernel, nameof(kernel));
33+
Guard.NotNull(optionsAction, nameof(optionsAction));
34+
Guard.NotEmpty(assembliesToScan, nameof(assembliesToScan));
35+
36+
var baseAssembly = Assembly.Load("DotNetToolkit.Repository");
37+
38+
var assToScan = !assembliesToScan.Any(x => x.FullName.Equals(baseAssembly.FullName))
39+
? assembliesToScan.Concat(new[] { baseAssembly })
40+
: assembliesToScan;
41+
42+
var types = assToScan.SelectMany(x => x.GetAccessibleTypes());
43+
44+
var interfaceTypesToScan = new[]
45+
{
46+
typeof(IService<>),
47+
typeof(IService<,>),
48+
typeof(IService<,,>),
49+
typeof(IService<,,,>),
50+
typeof(IRepository<>),
51+
typeof(IRepository<,>),
52+
typeof(IRepository<,,>),
53+
typeof(IRepository<,,,>),
54+
typeof(IReadOnlyService<>),
55+
typeof(IReadOnlyService<,>),
56+
typeof(IReadOnlyService<,,>),
57+
typeof(IReadOnlyService<,,,>),
58+
typeof(IReadOnlyRepository<>),
59+
typeof(IReadOnlyRepository<,>),
60+
typeof(IReadOnlyRepository<,,>),
61+
typeof(IReadOnlyRepository<,,,>),
62+
typeof(IRepositoryInterceptor)
63+
};
64+
65+
// Gets all the interfaces that inherent from IRepository<> or IRepositoryInterceptor
66+
var interfaceTypes = interfaceTypesToScan
67+
.SelectMany(interfaceType => types.Where(t => !t.IsClass && t.ImplementsInterface(interfaceType)))
68+
.Distinct();
69+
70+
var serviceTypesMapping = interfaceTypes
71+
.SelectMany(interfaceType => types.Where(t => t.IsClass && !t.IsAbstract && t.ImplementsInterface(interfaceType))
72+
.GroupBy(t => interfaceType, t => t));
73+
74+
// Binds the repositories and interceptors that have been scanned
75+
var optionsBuilder = new RepositoryOptionsBuilder();
76+
77+
optionsAction(optionsBuilder);
78+
79+
var registeredInterceptorTypes = new List<Type>();
80+
81+
foreach (var t in serviceTypesMapping)
82+
{
83+
var serviceType = t.Key;
84+
var implementationTypes = t.Where(x => x.IsGenericType == serviceType.IsGenericType &&
85+
x.GetGenericArguments().Length == serviceType.GetGenericArguments().Length &&
86+
x.IsVisible && !x.IsAbstract);
87+
88+
foreach (var implementationType in implementationTypes)
89+
{
90+
if (serviceType == typeof(IRepositoryInterceptor))
91+
{
92+
if (kernel.GetBindings(implementationType).Any() || optionsBuilder.Options.Interceptors.ContainsKey(implementationType))
93+
continue;
94+
95+
kernel.Bind(implementationType).ToSelf();
96+
kernel.Bind(serviceType).To(implementationType);
97+
registeredInterceptorTypes.Add(implementationType);
98+
}
99+
else
100+
{
101+
kernel.Bind(serviceType).To(implementationType);
102+
}
103+
}
104+
}
105+
106+
// Binds other services
107+
kernel.Bind<IRepositoryFactory>().To<RepositoryFactory>();
108+
kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
109+
kernel.Bind<IUnitOfWorkFactory>().To<UnitOfWorkFactory>();
110+
kernel.Bind<IRepositoryOptions>().ToMethod(c =>
111+
{
112+
var options = new RepositoryOptions(optionsBuilder.Options);
113+
114+
foreach (var interceptorType in registeredInterceptorTypes)
115+
{
116+
options.With(interceptorType, () => (IRepositoryInterceptor)c.Kernel.Get(interceptorType));
117+
}
118+
119+
return options;
120+
});
121+
122+
// Binds resolver
123+
RepositoryDependencyResolver.SetResolver(type => kernel.Get(type));
124+
}
125+
126+
/// <summary>
127+
/// Binds all the repositories services using the specified options builder.
128+
/// </summary>
129+
/// <param name="kernel">The kernel.</param>
130+
/// <param name="optionsAction">A builder action used to create or modify options for the repositories.</param>
131+
/// <remarks>
132+
/// This method will scan for repositories and interceptors from the assemblies that have been loaded into the
133+
/// execution context of this application domain, and will bind them to the container.
134+
/// </remarks>
135+
public static void RegisterRepositories([NotNull] this IKernel kernel, [NotNull] Action<RepositoryOptionsBuilder> optionsAction)
136+
{
137+
BindRepositories(kernel, optionsAction, AppDomain.CurrentDomain.GetAssemblies());
138+
}
139+
}
140+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# How to Use?
2+
3+
```csharp
4+
// kernel
5+
var kernel = new StandardKernel();
6+
7+
// new extension methods for the kernel container, which will bind all the repositories
8+
kernel.BindRepositories(options => options.UseInMemoryDatabase());
9+
```

0 commit comments

Comments
 (0)