Created
June 11, 2016 10:21
-
-
Save farhad-taran/f400244aec9c5a10322ff533c8e8febc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class KernelExtensions | |
{ | |
/// <summary> | |
/// Binds an open generic type to its implementation and adds all its defined decorators | |
/// </summary> | |
/// <param name="kernel">Ninject Container</param> | |
/// <param name="openGenericType">Open generic Type</param> | |
/// <param name="assembly">Assembly to scan for the open generic type implementation</param> | |
/// <param name="decoratorTypes">Types of the decorators. Order matters. Order is from the most outer decorator to the inner decorator</param> | |
public static void BindManyOpenGenericsWithDecorators(this IKernel kernel, Type openGenericType, Assembly assembly, params Type[] decoratorTypes) | |
{ | |
var allImplementations = GetAllTypesImplementingOpenGenericType(openGenericType, assembly); | |
foreach (var type in allImplementations.Where(type => !decoratorTypes.Contains(type))) | |
{ | |
var genericInterface = type.GetInterfaces().FirstOrDefault(x => openGenericType.IsAssignableFrom(x.GetGenericTypeDefinition())); | |
// real implementation | |
var parentType = decoratorTypes.Last(); | |
kernel.Bind(genericInterface).To(type) | |
.WhenInjectedInto(parentType); | |
} | |
for (var i = 0; i <= decoratorTypes.Count() - 1; i++) | |
{ | |
var decoratorType = decoratorTypes[i]; | |
if (i == 0) | |
{ | |
// most outer decorator | |
kernel.Bind(openGenericType).To(decoratorType); | |
} | |
else | |
{ | |
// inner decorators | |
var parentType = decoratorTypes[i - 1]; | |
kernel.Bind(openGenericType).To(decoratorType) | |
.WhenInjectedInto(parentType); | |
} | |
} | |
} | |
private static IEnumerable<Type> GetAllTypesImplementingOpenGenericType(Type openGenericType, Assembly assembly) | |
{ | |
return (from type in assembly.GetTypes() | |
from interfaceType in type.GetInterfaces() | |
let baseType = type.BaseType | |
where | |
(baseType != null && baseType.IsGenericType && | |
openGenericType.IsAssignableFrom(baseType.GetGenericTypeDefinition())) || | |
(interfaceType.IsGenericType && | |
openGenericType.IsAssignableFrom(interfaceType.GetGenericTypeDefinition())) | |
select type); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment