forked from ServiceStack/ServiceStack.Text
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAssemblyUtils.cs
More file actions
132 lines (117 loc) · 4.3 KB
/
AssemblyUtils.cs
File metadata and controls
132 lines (117 loc) · 4.3 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
130
131
132
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Threading;
using ServiceStack.Common.Support;
namespace ServiceStack.Text
{
/// <summary>
/// Utils to load types
/// </summary>
public static class AssemblyUtils
{
private const string FileUri = "file:///";
private const char UriSeperator = '/';
private static Dictionary<string, Type> TypeCache = new Dictionary<string, Type>();
#if !XBOX
/// <summary>
/// Find the type from the name supplied
/// </summary>
/// <param name="typeName">[typeName] or [typeName, assemblyName]</param>
/// <returns></returns>
public static Type FindType(string typeName)
{
Type type = null;
if (TypeCache.TryGetValue(typeName, out type)) return type;
#if !SL5
type = Type.GetType(typeName);
#endif
if (type == null)
{
var typeDef = new AssemblyTypeDefinition(typeName);
type = !string.IsNullOrEmpty(typeDef.AssemblyName)
? FindType(typeDef.TypeName, typeDef.AssemblyName)
: FindTypeFromLoadedAssemblies(typeDef.TypeName);
}
Dictionary<string, Type> snapshot, newCache;
do
{
snapshot = TypeCache;
newCache = new Dictionary<string, Type>(TypeCache);
newCache[typeName] = type;
} while (!ReferenceEquals(
Interlocked.CompareExchange(ref TypeCache, newCache, snapshot), snapshot));
return type;
}
#endif
/// <summary>
/// The top-most interface of the given type, if any.
/// </summary>
public static Type MainInterface<T>()
{
var t = typeof(T);
if (t.BaseType() == typeof(object))
{
// on Windows, this can be just "t.GetInterfaces()" but Mono doesn't return in order.
var interfaceType = t.Interfaces().FirstOrDefault(i => !t.Interfaces().Any(i2 => i2.Interfaces().Contains(i)));
if (interfaceType != null) return interfaceType;
}
return t; // not safe to use interface, as it might be a superclass's one.
}
/// <summary>
/// Find type if it exists
/// </summary>
/// <param name="typeName"></param>
/// <param name="assemblyName"></param>
/// <returns>The type if it exists</returns>
public static Type FindType(string typeName, string assemblyName)
{
var type = FindTypeFromLoadedAssemblies(typeName);
if (type != null)
{
return type;
}
return PclExport.Instance.FindType(typeName, assemblyName);
}
public static Type FindTypeFromLoadedAssemblies(string typeName)
{
var assemblies = PclExport.Instance.GetAllAssemblies();
foreach (var assembly in assemblies)
{
var type = assembly.GetType(typeName);
if (type != null)
{
return type;
}
}
return null;
}
public static Assembly LoadAssembly(string assemblyPath)
{
return PclExport.Instance.LoadAssembly(assemblyPath);
}
public static string GetAssemblyBinPath(Assembly assembly)
{
var codeBase = PclExport.Instance.GetAssemblyCodeBase(assembly);
var binPathPos = codeBase.LastIndexOf(UriSeperator);
var assemblyPath = codeBase.Substring(0, binPathPos + 1);
if (assemblyPath.StartsWith(FileUri, StringComparison.OrdinalIgnoreCase))
{
assemblyPath = assemblyPath.Remove(0, FileUri.Length);
}
return assemblyPath;
}
static readonly Regex versionRegEx = new Regex(", Version=[^\\]]+", PclExport.Instance.RegexOptions);
public static string ToTypeString(this Type type)
{
return versionRegEx.Replace(type.AssemblyQualifiedName, "");
}
public static string WriteType(Type type)
{
return type.ToTypeString();
}
}
}