从本文标题中可以看出,主要说的是反射技术和控制反转(IOC)技术,本文主要先介绍一下我对这两种技术的理解及它们的优缺点,最后再用实例来说一下使用方法。
反射:可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。这里,它最重要的是“动态性”,即根据条件动态创建“指定类型”的“实例”。
1 // Using GetType to obtain type information:
2 int i = 42;
3 System.Type type = i.GetType();
4
结果是:
System.Int32
本示例使用静态方法 GetType(Object 基类派生的所有类型都继承该方法) 获取变量类型的简单反射实例
1 // Using Reflection to get information from an Assembly:
2 System.Reflection.Assembly o = System.Reflection.Assembly.Load("mscorlib.dll");
3
结果是:
mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
本示例使用反射获取已加载的程序集的完整名称
反射一般用在以下情况中:
- 需要访问程序元数据的属性。linq to sql 中使用很多
- 执行后期绑定,访问在运行时创建的类型的方法。与工厂模式一起使用,根据配置文件中的类型来动态建立实例
IOC:(Inversion of Control,英文缩写为IoC)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题。 控制反转还有一个名字叫做依赖注入(Dependency Injection)。简称DI。实现IOC的架构有很多如:Avalon 、Spring、JBoss及Unity等。
理解IOC:可以把IoC模式看做是工厂模式的升华,可以把IoC看作是一个大工厂,只不过这个大工厂里要生成的对象都是在XML文件中给出定义的,然后利用Java 的“反射”编程,根据XML中给出的类名生成相应的对象。
实现非常简单,根据容易名称去创建对象即可
1 /// <summary>
2 /// The static factory of container
3 /// </summary>
4 public sealed class ContainerManager
5 {
6 /// <summary>
7 /// Creates the specified container instance .
8 /// </summary>
9 /// <param name="containerName">Name of the container.</param>
10 /// <returns></returns>
11 public static IContainerContext GetContainer(string containerName)
12 {
13 return new UnityContainerContext(containerName);
14 }
15
以下是在实际项目中的使用,IOC架构是用Unity,它的基础代码是:
1 /// <summary>
2 /// The specific container context for Unity
3 /// </summary>
4 public class UnityContainerContext : ContainerContextBase
5 {
6 #region Fields
7
8 /// <summary>
9 /// The lock used for synchronous
10 /// </summary>
11 private static readonly object _synlock = new object();
12
13 #endregion
14
15 #region Constructor
16
17 /// <summary>
18 /// Initializes a new instance of the <see cref="UnityContainerContext"/> class.
19 /// </summary>
20 /// <param name="name">The name.</param>
21 public UnityContainerContext(string name)
22 : base(name)
23 {
24 }
25
26 #endregion
27
28 #region Properties
29
30 /// <summary>
31 /// Gets the current context.
32 /// </summary>
33 /// <value>The current context.</value>
34 private HttpContext CurrentContext
35 {
36 get
37 {
38 HttpContext context = HttpContext.Current;
39 if (context == null)
40 {
41 throw new Exception("The current httpcontext is null");
42 }
43 return context;
44 }
45 }
46
47 #endregion
48
49 #region Override Methods
50
51 /// <summary>
52 /// Initializes container.
53 /// </summary>
54 public override void Initialize()
55 {
56 OnBeforeInitialized(new ContainerEventArgs(this, ContainerType.Unity));
57
58 if (CurrentContext.Application[Name] == null)
59 {
60 lock (_synlock)
61 {
62 if (CurrentContext.Application[Name] == null)
63 {
64 IUnityContainer currentContainer = new UnityContainer();
65 UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
66 section.Containers[Name].Configure(currentContainer);
67 CurrentContext.Application[Name] = currentContainer;
68 }
69 }
70 }
71
72 OnAfterInitialized(new ContainerEventArgs(this, ContainerType.Unity));
73 }
74
75 /// <summary>
76 /// Resolves this instance.
77 /// </summary>
78 /// <typeparam name="T">Parameter type.</typeparam>
79 /// <returns></returns>
80 public override T Resolve<T>()
81 {
82 try
83 {
84 Initialize();
85
86 IUnityContainer currentContainer = CurrentContext.Application[Name] as IUnityContainer;
87 return currentContainer.Resolve<T>();
88 }
89 catch(Exception ex)
90 {
91 OnResolveFailed(new ContainerFailedEventArgs(this, ContainerType.Unity, ex));
92 return default(T);
93 }
94 }
95
96 /// <summary>
97 /// Tears down.
98 /// </summary>
99 public override void TearDown()
100 {
101 OnBeforeTearDown(new ContainerEventArgs(this, ContainerType.Unity));
102
103 CurrentContext.Application[Name] = null;
104
105 OnAfterTearDown(new ContainerEventArgs(this, ContainerType.Unity));
106 }
107
108 #endregion
109
110
在项目中通过unity来创建对象的代码是:
1 /// <summary>
2 /// 数据层实体的个性操作对象
3 /// </summary>
4 /// <typeparam name="TEntity"></typeparam>
5 /// <returns></returns>
6 protected TEntity LoadRepositoryEntity<TEntity>()
7 {
8 IContainerContext container = ContainerManager.GetContainer("repositoryContainer");
9 return container.Resolve<TEntity>();
10
这样,在BLL层调用DAL层对象时,可以通过LoadRepositoryEntity泛型方法来实现。
作者:仓储大叔,张占岭,
荣誉:微软MVP