-
Notifications
You must be signed in to change notification settings - Fork 0
/
TypeAutoInjection.cs
118 lines (108 loc) · 4.95 KB
/
TypeAutoInjection.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
using TypeAutoInjector.Attributes;
using TypeAutoInjector.Enums;
namespace TypeAutoInjector
{
public static class TypeAutoInjection
{
public static IServiceCollection Inject(this IServiceCollection collection, TypeLifeScope scope,
AssemblyName assemblyName,
string typeNameEndsWith, bool hasInterfaces, Action<string> logMessageAction)
{
switch (hasInterfaces)
{
case true:
{
var assembly = Assembly.Load(assemblyName);
var interfaces = assembly.GetTypes().Where(t => t.IsInterface).ToList();
foreach (var type in assembly.GetTypes())
{
if (!type.IsClass || type.IsAbstract || type.IsGenericType ||
!type.Name.EndsWith(typeNameEndsWith))
continue;
if (type.GetCustomAttribute(typeof(NotAutoInjectTypeAttribute)) != null)
continue;
var typeInterfaceName = $"I{type.Name}";
var typeInterface = interfaces.Find(t => t.Name == typeInterfaceName);
if (typeInterface?.GetCustomAttribute(typeof(NotAutoInjectTypeAttribute)) != null)
continue;
if (type.GetInterface(typeInterfaceName) == null)
throw new NotImplementedException(
$"{typeInterface?.Name} does not implement on {type.Name}");
AddTypeWithInterface(logMessageAction, collection, scope, type, typeInterface);
}
break;
}
case false:
{
var assembly = Assembly.Load(assemblyName);
foreach (var type in assembly.GetTypes())
{
if (!type.IsClass
|| type.IsAbstract
|| !type.Name.EndsWith(typeNameEndsWith)
|| type.GetCustomAttribute(typeof(NotAutoInjectTypeAttribute)) != null)
continue;
AddTypeWithoutInterface(logMessageAction, collection, scope, type);
}
break;
}
}
return collection;
}
private static void AddTypeWithoutInterface(Action<string> logMessageAction, IServiceCollection collection,
TypeLifeScope scope, Type type)
{
logMessageAction.Invoke($"{type.Name} found.");
switch (scope)
{
case TypeLifeScope.Transient:
collection.AddTransient(type);
logMessageAction.Invoke(
$"{type.Name} injected as {scope} successfully.");
break;
case TypeLifeScope.Scoped:
collection.AddScoped(type);
logMessageAction.Invoke(
$"{type.Name} injected as {scope} successfully.");
break;
case TypeLifeScope.Singleton:
collection.AddSingleton(type);
logMessageAction.Invoke(
$"{type.Name} injected as {scope} successfully.");
break;
default:
throw new ArgumentOutOfRangeException(nameof(scope), scope, null);
}
}
private static void AddTypeWithInterface(Action<string> logMessageAction, IServiceCollection collection,
TypeLifeScope scope,
Type type, Type typeInterface)
{
logMessageAction.Invoke($"{typeInterface.Name} interface found for {type.Name}");
switch (scope)
{
case TypeLifeScope.Transient:
collection.AddTransient(type, typeInterface);
logMessageAction.Invoke(
$"{type.Name} with interface {typeInterface.Name} injected as {scope} successfully.");
break;
case TypeLifeScope.Scoped:
collection.AddScoped(type, typeInterface);
logMessageAction.Invoke(
$"{type.Name} with interface {typeInterface.Name} injected as {scope} successfully.");
break;
case TypeLifeScope.Singleton:
collection.AddSingleton(type, typeInterface);
logMessageAction.Invoke(
$"{type.Name} with interface {typeInterface.Name} injected as {scope} successfully.");
break;
default:
throw new ArgumentOutOfRangeException(nameof(scope), scope, null);
}
}
}
}