-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServiceLocator.cs
More file actions
129 lines (116 loc) · 4.7 KB
/
Copy pathServiceLocator.cs
File metadata and controls
129 lines (116 loc) · 4.7 KB
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
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Maverick
{
public static class ServiceLocator
{
public static void Initialize()
{
try
{
foreach (string serviceMap in Properties.Settings.Default.ServiceMap.Split(',').Where(i => !string.IsNullOrWhiteSpace(i)))
{
string[] serviceMapPair = serviceMap.Split(':');
if (serviceMapPair.Length > 2) { throw new InvalidOperationException(String.Format("Service map {0} invalid.",serviceMap)); }
Type concreteType;
if ((concreteType = GetType(serviceMapPair[1])) != null)
{
MapType(GetType(serviceMapPair[0]), concreteType);
}
else
{
MapConstructor(GetType(serviceMapPair[0]), () => createInstanceFromTypeOrConstructor(GetType(serviceMapPair[1])));
}
}
}
catch (Exception e)
{
throw new Exception("Unable to parse service map: " + e.Message, e);
}
}
public static T Resolve<T>()
where T:class
{
return (T)Resolve(typeof(T));
}
public static object Resolve(Type type)
{
object concreteTypeOrConstructor;
try
{
concreteTypeOrConstructor = _map[type];
}
catch (KeyNotFoundException knfe)
{
throw new Exception("Unable to resolve type:\n Not mapped: " + type.ToString());
}
return createInstanceFromTypeOrConstructor(concreteTypeOrConstructor);
}
private static object createInstanceFromTypeOrConstructor(object typeOrConstructor)
{
try
{
if (typeOrConstructor is Type)
{
return Activator.CreateInstance((Type)typeOrConstructor);
}
if (typeOrConstructor is Func<object>)
{
return ((Func<object>)typeOrConstructor)();
}
throw new Exception("Invalid concrete type or constructor.");
}
catch (Exception e)
{
throw new Exception("Unable to create instance of " + typeOrConstructor.ToString() + "\nPreserved exception:\n" + Utility.ExceptionToString(e));
}
}
static Dictionary<Type, object> _map = new Dictionary<Type, object>();
public static void MapType<TAbstract, TConcrete>()
where TAbstract:class
where TConcrete:new()
{
MapType(typeof(TAbstract), typeof(TConcrete));
}
public static void MapType(Type abstractType, Type concreteType)
{
map(abstractType, concreteType);
}
public static void MapConstructor<TAbstract>(Func<object> constructor)
{
MapConstructor(typeof(TAbstract),constructor);
}
public static void MapConstructor(Type abstractType, Func<object> constructor)
{
map(abstractType,constructor);
}
static void map(Type abstractType, object concreteTypeOrConstructor)
{
_map[abstractType] = concreteTypeOrConstructor;
}
public static Type GetType(string typeIdentifier)
{
string typeNamespace = "";
string type = "";
if (typeIdentifier.Contains('.'))
{
typeNamespace = typeIdentifier.Split('.').First();
type = typeIdentifier.Split('.').Last();
}
else { type = typeIdentifier; }
return Type.GetType(type, null, new Func<Assembly, string, bool, Type>(
(assembly, typename, throwErr) => {
return Type.GetType(type) ??
Type.GetType(typeIdentifier) ??
Type.GetType(typeNamespace + "." + typename + ", " + typeNamespace) ??
Type.GetType(typeNamespace + "." + typename + ", " + "MaverickDynamic") ??
Type.GetType("MaverickDynamic." + typename + ", MaverickDynamic") ??
Type.GetType("Maverick." + typename + ", Maverick"); }));
}
}
}