博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
架构,改善程序复用性的设计~第五讲 复用离不开反射和IOC
阅读量:7209 次
发布时间:2019-06-29

本文共 5336 字,大约阅读时间需要 17 分钟。

从本文标题中可以看出,主要说的是反射技术和控制反转(IOC)技术,本文主要先介绍一下我对这两种技术的理解及它们的优缺点,最后再用实例来说一下使用方法。

反射:可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性。这里,它最重要的是“动态性”,即根据条件动态创建“指定类型”的“实例”。

1 // Using GetType to obtain type information:2 int i = 42;3 System.Type type = i.GetType();4 System.Console.WriteLine(type);

结果是:

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 System.Console.WriteLine(o.GetName());

结果是:

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     ///  2     /// The static factory of container 3     ///  4     public sealed class ContainerManager 5     { 6         ///  7         /// Creates the specified container instance . 8         ///  9         /// Name of the container.10         /// 
11 public static IContainerContext GetContainer(string containerName)12 {13 return new UnityContainerContext(containerName);14 }15 }

以下是在实际项目中的使用,IOC架构是用Unity,它的基础代码是:

1     ///   2     /// The specific container context for Unity  3     ///   4     public class UnityContainerContext : ContainerContextBase  5     {  6         #region Fields  7   8         ///   9         /// The lock used for synchronous 10         ///  11         private static readonly object _synlock = new object(); 12  13         #endregion 14  15         #region Constructor 16  17         ///  18         /// Initializes a new instance of the 
class. 19 ///
20 /// The name. 21 public UnityContainerContext(string name) 22 : base(name) 23 { 24 } 25 26 #endregion 27 28 #region Properties 29 30 /// 31 /// Gets the current context. 32 /// 33 ///
The current context.
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 /// 52 /// Initializes container. 53 /// 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 /// 76 /// Resolves this instance. 77 /// 78 ///
Parameter type.
79 ///
80 public override T Resolve
() 81 { 82 try 83 { 84 Initialize(); 85 86 IUnityContainer currentContainer = CurrentContext.Application[Name] as IUnityContainer; 87 return currentContainer.Resolve
(); 88 } 89 catch(Exception ex) 90 { 91 OnResolveFailed(new ContainerFailedEventArgs(this, ContainerType.Unity, ex)); 92 return default(T); 93 } 94 } 95 96 ///
97 /// Tears down. 98 /// 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 #endregion109 110 }

在项目中通过unity来创建对象的代码是:

1         ///  2         /// 数据层实体的个性操作对象 3         ///  4         /// 
5 ///
6 protected TEntity LoadRepositoryEntity
() 7 { 8 IContainerContext container = ContainerManager.GetContainer("repositoryContainer"); 9 return container.Resolve
();10 }

这样,在BLL层调用DAL层对象时,可以通过LoadRepositoryEntity泛型方法来实现。

本文转自博客园张占岭(仓储大叔)的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
MySql的一些用法
查看>>
DAMICON'S LIST OF OPEN SOFTWARE
查看>>
js-用于检测类数组对象的函数
查看>>
php 获取客户端的浏览器信息
查看>>
JavaScript------获取表单信息
查看>>
R语言︱文本挖掘——词云wordcloud2包
查看>>
Chapter 3 Phenomenon——18
查看>>
hibernate+spring整合增删改事务错误
查看>>
怎样理解阻塞与非阻塞、同步与异步的区别?
查看>>
C语言不定参数
查看>>
Python第十五天 datetime模块 time模块 thread模块 threading模块 Queue队列模块 multiprocessing模块 paramiko模块 fab...
查看>>
在JavaScript中对HTML进行反转义
查看>>
面向服务的架构SOA
查看>>
WinForm 窗体初始位置篇
查看>>
PowerShell发送邮件(587)
查看>>
Chapter 3 Phenomenon——23
查看>>
自动化测试如何解决验证码的问题
查看>>
利用位操作的几道题目
查看>>
导入时如何定制spring-boot依赖项的版本
查看>>
31:字符串p型编码
查看>>