1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
5
namespace JasonNet.Platform.Common
6
{
7
/// <summary>
8
/// <see cref="DefaultImplementationAttribute"/>标签用于定义一个接口的默认实现类型。
9
/// </summary>
10
/// Title: DefaultImplementationAttribute
11
/// Author: 姜辉
12
/// Version: 1.0
13
/// History:
14
/// 2006-07-13 姜辉 [创建]
15
16
[AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
17
public sealed class DefaultImplementationAttribute : Attribute
18
{
19
private Type defaultImplementationType;
20
private string defaultImplementationTypeFullName;
21
22
/// <summary>
23
/// <see cref="DefaultImplementationAttribute"/>的构造函数。
24
/// </summary>
25
/// <param name="defaultImplementationType">指定接口的默认实现类型</param>
26
public DefaultImplementationAttribute(Type defaultImplementationType)
27
{
28
this.defaultImplementationType = defaultImplementationType;
29
}
30
31
/// <summary>
32
/// <see cref="DefaultImplementationAttribute"/>的构造函数。
33
/// </summary>
34
/// <param name="defaultImplementationTypeFullName">指定接口的默认实现类型的字符串表达形式</param>
35
public DefaultImplementationAttribute(string defaultImplementationTypeFullName)
36
{
37
this.defaultImplementationTypeFullName = defaultImplementationTypeFullName;
38
}
39
40
/// <summary>
41
/// 指定接口的默认实现类型。
42
/// </summary>
43
public Type DefaultImplementationType
44
{
45
get
46
{
47
return defaultImplementationType;
48
}
49
}
50
51
/// <summary>
52
/// 指定接口的默认实现类型的字符串表达形式。
53
/// </summary>
54
public string DefaultImplementationTypeFullName
55
{
56
get
57
{
58
return defaultImplementationTypeFullName;
59
}
60
}
61
}
62
}

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

2.定义构造容器
1
using System;
2
using System.IO;
3
using System.Globalization;
4
using System.Collections.Generic;
5
using System.Text;
6
using System.Reflection;
7
using Microsoft.Practices.ObjectBuilder;
8
9
using JasonNet.Platform.Common.Properties;
10
11
namespace JasonNet.Platform.Common
12
{
13
/// <summary>
14
/// <see cref="ObjectContainer"/>用于创建、获取容器中的对象实例。
15
/// Title: ObjectContainer
16
/// Author: 姜辉
17
/// Version: 1.0
18
/// History:
19
/// 2006-07-13 姜辉 [创建]
20
21
public static class ObjectContainer
22
{
23
private static IBuilder<BuilderStage> builder = new Builder();
24
private static Locator locator = new Locator();
25
26
private const string InterfacePrefix = "I";
27
private const string AbstractClassPrefix = "Base";
28
private const string DefaultImplNamespaceSuffix = "DefaultImpl.";
29
30
/// <summary>
31
/// 根据指定的对象类型构造对象实例。
32
/// </summary>
33
/// <remarks>
34
/// <para>
35
/// <see cref="ObjectContainer"/>不支持简单值类型的构造,因此,如果<typeparamref name="T"/>是简单值类型,
36
/// 将抛出<see cref="ArgumentException"/>。
37
/// </para>
38
/// <para>
39
/// 如果<typeparamref name="T"/>是非静态的实现类,则直接构建<typeparamref name="T"/>的对象实例。
40
/// </para>
41
/// <para>
42
/// 如果<typeparamref name="T"/>是接口或抽象类,则<see cref="ObjectContainer"/>将按以下规则来创建该接口
43
/// 或抽象类的实现类对象实例:
44
/// <list type="bullet">
45
/// <item>
46
/// <description>
47
/// 首先检测<typeparamref name="T"/>是否标记了<see cref="DefaultImplementationAttribute"/>标签来指定默认
48
/// 的实现类,如果指定了合法的默认实现类,则会构造出指定的默认实现类的对象实例;如果通过标签指定的默认实
49
/// 现类不合法,则会抛出<see cref="TypeNotMatchException"/>或<see cref="DefaultImplementationNotFoundException"/>异常。
50
/// </description>
51
/// </item>
52
/// <item>
53
/// <description>
54
/// 如果<typeparamref name="T"/>没有使用<see cref="DefaultImplementationAttribute"/>标签来指定默认的实现
55
/// 类,则会根据<c>JasonNet</c>平台默认的匹配关系(默认实现类的命名空间为接口命名空间 + ".DefaultImpl",
56
/// 类名为接口名称去掉前缀“I”,或基类名称去掉“Base”)来查找默认实现类,如果能够找到,则构造出该默认
57
/// 实现类的对象实例,如果无法找到,则抛出<see cref="DefaultImplementationNotFoundException"/>异常。
58
/// </description>
59
/// </item>
60
/// </list>
61
/// </para>
62
/// <para>
63
/// 从以上对于接口或抽象类的默认实现对象的构造规则中可以看出,要成功构造一个接口或抽象类的默认实现类对象
64
/// ,需要满足以下任意一项:
65
/// <list type="number">
66
/// <item>
67
/// <description>对<typeparamref name="T"/>使用<see cref="DefaultImplementationAttribute"/>进行了正确的
68
/// 配置,即<see cref="DefaultImplementationAttribute"/>指定的默认实现类确实实现了<typeparamref name="T"/>
69
/// 接口或抽象类。</description>
70
/// </item>
71
/// <item>
72
/// <description>
73
/// 如果<typeparamref name="T"/>没有使用<see cref="DefaultImplementationAttribute"/>标签来指定默认的实现
74
/// 类,则要求<typeparamref name="T"/>接口或抽象类、以及默认实现类的命名都遵循以下规范:1,接口必须以<c>
75
/// I</c>作前缀,抽象类必须以<c>Base</c>作前缀;2,默认实现类的命名空间为接口命名空间 + ".DefaultImpl";
76
/// 3,默认实现类的名称为接口名称去掉前缀“I”,或抽象类的名称去掉前缀“Base”,如下例所示:
77
/// </description>
78
/// </item>
79
/// </list>
80
/// <example>
81
/// 以下是使用<see cref="DefaultImplementationAttribute"/>来配置接口与其默认实现类的示例,该情况下使用本
82
/// 方法传入IUserManager接口可以构造出UserManager的实例。
83
/// <code>
84
/// namespace JasonNet.Platform.Security
85
/// {
86
/// [DefaultImplementation(typeof(JasonNet.Platform.Security.UserManager))]
87
/// public interface IUserManager {}
88
/// }
89
///
90
/// namespace JasonNet.Platform.Security
91
/// {
92
/// public class UserManager : IUserManager {}
93
/// }
94
/// </code>
95
/// 以下是使用<see cref="DefaultImplementationAttribute"/>来配置抽象类与其默认实现类的示例,该情况下使用
96
/// 本方法传入BizLogDatabaseAdapter抽象类可以构造出基于SQL Server实现的SqlBizLogDatabaseAdapter的实例。
97
/// <code>
98
/// namespace JasonNet.Platform.Logging.Database
99
/// {
100
/// [DefaultImplementation(typeof(JaonNet.Platform.Logging.Database.SqlBizLogDatabaseAdapter))]
101
/// public abstract class BizLogDatabaseAdapter {}
102
/// }
103
///
104
/// namespace JasonNet.Platform.Logging.Database
105
/// {
106
/// public class SqlBizLogDatabaseAdapter : BizLogDatabaseAdapter {}
107
/// }
108
/// </code>
109
/// 以下是按<c>JasonNet平台默认的匹配关系</c>定义的接口与其默认实现类的示例,该情况下使用本方法传入
110
/// IUserManager接口可以构造出UserManager的实例。
111
/// <code>
112
/// namespace JasonNet.Platform.Security
113
/// {
114
/// public interface IUserManager {}
115
/// }
116
///
117
/// namespace JasonNet.Platform.Security.DefaultImpl
118
/// {
119
/// public class UserManager : IUserManager {}
120
/// }
121
/// </code>
122
/// 以下是按<c>JasonNet平台默认的匹配关系</c>定义的抽象类与其默认实现类的示例,该情况下使用本方法传入
123
/// BaseBizLogDatabaseAdapter抽象类可以构造出BizLogDatabaseAdapter的实例。
124
/// <code>
125
/// namespace JasonNet.Platform.Logging.Database
126
/// {
127
/// public abstract class BaseBizLogDatabaseAdapter {}
128
/// }
129
///
130
/// namespace JasonNet.Platform.Logging.Database.DefaultImpl
131
/// {
132
/// public class BizLogDatabaseAdapter : BaseBizLogDatabaseAdapter {}
133
/// }
134
/// </code>
135
/// 以下是按<c>JasonNet</c>平台为解决工程间循环引用实现类的示例,该情况下使用本方法传入
136
/// 指定接口的默认实现类型的字符串表达形式来构造出其实例。
137
/// <code>
138
/// namespace *****.****.DE.InnerInterfaces
139
/// {
140
/// [DefaultImplementation("*****.****.DE.DE.BusinessLogic.DesignProxyServiceFacade,*****.****.DE.BusinessLogic")]
141
/// public interface IDeDeInnerInterface
142
/// {
143
/// IList<String> GetDesignCompanyByProjectNo(string projectNo);
144
/// }
145
/// }
146
/// namespace *****.****.**.DE.InnerInterfaces
147
/// {
148
/// public interface IDesignProxyServiceFacade : IDeDeInnerInterface
149
/// {
150
/// 此处回到配置接口与其默认实现类的示例
151
/// }
152
/// </code>
153
/// </example>
154
/// </para>
155
/// <para>
156
/// 对于以上各种情况的实现类对象实例的创建,默认情况下,都将使用实现类的第一个构造函数来构造对象实例,
157
/// 如果第一个构造函数中含有参数,则对于简单值类型以该类型的默认值为参数值;对于对象类型,会在容器中去
158
/// 查找是否已经有该类型的对象存在,如果存在,则用该对象作为参数值,如果不存在则构造一个新的该类型的对
159
/// 象作为参数值(在构造该类型的对象时如果又需要参数,则类似地按上述步骤进行,即一层层地递归往下找,直
160
/// 到所有的依赖对象都被构造后,该对象才会被构造)。由于带参数的构造方式非常复杂,强烈建议使用不带参数
161
/// 的构造函数来构造对象,即始终把不带参数的构造函数放在代码的最前面。
162
/// </para>
163
/// </remarks>
164
/// <typeparam name="T">要构造的对象的类型</typeparam>
165
/// <returns>构造的对象实例</returns>
166
/// <exception cref="ArgumentException">
167
/// 当<typeparamref name="T"/>是简单值类型、或在T(或T的默认实现类)中无法找到构造所需的构造函数时抛出
168
/// 的异常。</exception>
169
/// <exception cref="TypeNotMatchException">
170
/// 当<typeparamref name="T"/>上的<see cref="DefaultImplementationAttribute"/>标签所指定的默认实现类类
171
/// 型与<typeparamref name="T"/>不匹配(并没有实现T或从T派生)时抛出的异常。</exception>
172
/// <exception cref="DefaultImplementationNotFoundException">
173
/// 当通过平台默认的匹配关系无法找到<typeparamref name="T"/>的默认实现类时所抛出的异常。
174
/// </exception>
175
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
176
public static T BuildUp<T>()
177
{
178
return (T)BuildUp(typeof(T));
179
}
180
181
internal static object BuildUp(Type typeToBuild)
182
{
183
Type reflectionType = null;
184
185
// typeToBuild 如果是值类型或者静态类时
186
if (typeToBuild.IsValueType || (typeToBuild.IsAbstract && typeToBuild.IsSealed))
187
{
188
throw new ArgumentException(
189
String.Format(CultureInfo.CurrentUICulture,
190
Resources.ExceptionTypeIsValueTypeOrStaticClass, typeToBuild.Name));
191
}
192
193
// typeToBuild是接口或抽象类
194
if (typeToBuild.IsAbstract)
195
{
196
object[] defaultImplAttrs = typeToBuild.GetCustomAttributes(typeof(DefaultImplementationAttribute), false);
197
if (defaultImplAttrs.Length == 0)
198
{
199
// 没有标签,按照默认规则寻找
200
201
// 如果类型的命名不符合规范,则抛出异常
202
if (!typeToBuild.Name.StartsWith(ObjectContainer.InterfacePrefix) &&
203
!typeToBuild.Name.StartsWith(ObjectContainer.AbstractClassPrefix))
204
{
205
throw new IllegalTypeNameException(new string[] { typeToBuild.FullName });
206
}
207
208
StringBuilder defaultImplTypeString = new StringBuilder();
209
defaultImplTypeString.Append(typeToBuild.FullName.Substring(0, typeToBuild.FullName.LastIndexOf(".") + 1));
210
defaultImplTypeString.Append(DefaultImplNamespaceSuffix);
211
212
if (typeToBuild.IsInterface)
213
{
214
// 接口名称去掉前缀“I”
215
defaultImplTypeString.Append(typeToBuild.Name.Substring(1));
216
}
217
else
218
{
219
//抽象类的名称去掉前缀“Base”
220
defaultImplTypeString.Append(typeToBuild.Name.Substring(4));
221
}
222
defaultImplTypeString.Append(", ");
223
defaultImplTypeString.Append(typeToBuild.Assembly.FullName);
224
225
reflectionType = SearchForTypeToBuild(defaultImplTypeString.ToString());
226
227
// 当没有找到默认实现类
228
// 或者找到的是仍然是接口或者抽象类时
229
if (reflectionType == null ||
230
!typeToBuild.IsAssignableFrom(reflectionType) ||
231
reflectionType.IsAbstract ||
232
reflectionType.IsInterface)
233
{
234
throw new DefaultImplementationNotFoundException(new string[] { typeToBuild.FullName });
235
}
236
}
237
else
238
{
239
// 有标签
240
DefaultImplementationAttribute defImpl = defaultImplAttrs[0] as DefaultImplementationAttribute;
241
242
if (!String.IsNullOrEmpty(defImpl.DefaultImplementationTypeFullName))
243
{
244
reflectionType = SearchForTypeToBuild(defImpl.DefaultImplementationTypeFullName);
245
}
246
else
247
{
248
reflectionType = defImpl.DefaultImplementationType;
249
}
250
251
// 标签所指定的默认实现类类型与typeToBuild不匹配(并没有实现typeToBuild或从typeToBuild派生)
252
// 或者默认的实现也是一个接口或抽象类
253
if (reflectionType == null)
254
{
255
throw new DefaultImplementationNotFoundException(new string[] { typeToBuild.FullName });
256
}
257
if (reflectionType == typeToBuild ||
258
!typeToBuild.IsAssignableFrom(reflectionType) ||
259
reflectionType.IsAbstract ||
260
reflectionType.IsInterface)
261
{
262
throw new TypeNotMatchException();
263
}
264
}
265
266
return builder.BuildUp(locator, reflectionType, null, null);
267
}
268
else
269
{
270
// T是非静态的实现类时,检查其是否具有有效的构造函数
271
if (typeToBuild.GetConstructors().Length == 0)
272
{
273
throw new ArgumentException(
274
String.Format(CultureInfo.CurrentUICulture,
275
Resources.ExceptionTypeHasNoConstructors, typeToBuild.Name));
276
}
277
278
return builder.BuildUp(locator, typeToBuild,null, null);
279
}
280
}
281
282
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
283
private static Type SearchForTypeToBuild(string defaultImplTypeString)
284
{
285
Type reflectedType = null;
286
287
try
288
{
289
reflectedType = Type.GetType(defaultImplTypeString);
290
}
291
catch
292
{
293
}
294
return reflectedType;
295
}
296
}
297
}
298

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

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298
