This repository has been archived by the owner on Nov 29, 2017. It is now read-only.
/
SqlTypesAssemblyLoader.cs
138 lines (122 loc) · 4.8 KB
/
SqlTypesAssemblyLoader.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
namespace System.Data.Entity.SqlServer
{
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity.SqlServer.Resources;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
internal class SqlTypesAssemblyLoader
{
private readonly IEnumerable<string> _preferredSqlTypesAssemblies;
private readonly Lazy<SqlTypesAssembly> _latestVersion;
public SqlTypesAssemblyLoader(IEnumerable<string> assemblyNames = null)
{
_preferredSqlTypesAssemblies
= assemblyNames
?? new[]
{
"Microsoft.SqlServer.Types, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91",
"Microsoft.SqlServer.Types, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91",
};
_latestVersion = new Lazy<SqlTypesAssembly>(BindToLatest, isThreadSafe: true);
}
/// <summary>
/// Returns the highest available version of the Microsoft.SqlServer.Types assembly that could be
/// located using Assembly.Load; may return <c>null</c> if no version of the assembly could be found.
/// </summary>
public virtual SqlTypesAssembly TryGetSqlTypesAssembly()
{
return _latestVersion.Value;
}
public virtual SqlTypesAssembly GetSqlTypesAssembly()
{
if (_latestVersion.Value == null)
{
throw new InvalidOperationException(Strings.SqlProvider_SqlTypesAssemblyNotFound);
}
return _latestVersion.Value;
}
public virtual bool TryGetSqlTypesAssembly(Assembly assembly, out SqlTypesAssembly sqlAssembly)
{
if (IsKnownAssembly(assembly))
{
sqlAssembly = new SqlTypesAssembly(assembly);
return true;
}
sqlAssembly = null;
return false;
}
private SqlTypesAssembly BindToLatest()
{
Assembly sqlTypesAssembly = null;
foreach (var assemblyFullName in _preferredSqlTypesAssemblies)
{
var asmName = new AssemblyName(assemblyFullName);
try
{
sqlTypesAssembly = Assembly.Load(asmName);
break;
}
catch (FileNotFoundException)
{
}
catch (FileLoadException)
{
}
}
if (sqlTypesAssembly != null)
{
return new SqlTypesAssembly(sqlTypesAssembly);
}
return null;
}
private bool IsKnownAssembly(Assembly assembly)
{
foreach (var knownAssemblyFullName in _preferredSqlTypesAssemblies)
{
if (AssemblyNamesMatch(assembly.FullName, new AssemblyName(knownAssemblyFullName)))
{
return true;
}
}
return false;
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
private static bool AssemblyNamesMatch(string infoRowProviderAssemblyName, AssemblyName targetAssemblyName)
{
if (string.IsNullOrWhiteSpace(infoRowProviderAssemblyName))
{
return false;
}
AssemblyName assemblyName;
try
{
assemblyName = new AssemblyName(infoRowProviderAssemblyName);
}
catch (Exception)
{
return false;
}
// Match the provider assembly details
if (!string.Equals(targetAssemblyName.Name, assemblyName.Name, StringComparison.OrdinalIgnoreCase))
{
return false;
}
if (targetAssemblyName.Version == null
|| assemblyName.Version == null)
{
return false;
}
if (targetAssemblyName.Version.Major != assemblyName.Version.Major
|| targetAssemblyName.Version.Minor != assemblyName.Version.Minor)
{
return false;
}
var targetPublicKeyToken = targetAssemblyName.GetPublicKeyToken();
return targetPublicKeyToken != null && targetPublicKeyToken.SequenceEqual(assemblyName.GetPublicKeyToken());
}
}
}