架构,改善程序复用性的设计~第五讲 复用离不开反射和IOC

简介:

从本文标题中可以看出,主要说的是反射技术和控制反转(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     /// <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泛型方法来实现。

本文转自博客园张占岭(仓储大叔)的博客,原文链接:架构,改善程序复用性的设计~第五讲 复用离不开反射和IOC,如需转载请自行联系原博主。

目录
相关文章
|
7月前
|
设计模式 前端开发 网络协议
软件体系结构 - 软件架构复用
软件体系结构 - 软件架构复用
283 0
|
7月前
|
SQL NoSQL 前端开发
基于BS架构的饰品购物平台设计与实现(程序+文档+数据库)
基于BS架构的饰品购物平台设计与实现(程序+文档+数据库)
|
6月前
|
缓存 C语言 计算机视觉
程序与技术分享:CPU0处理器的架构及应用
程序与技术分享:CPU0处理器的架构及应用
|
4月前
|
存储 算法 前端开发
JVM架构与主要组件:了解Java程序的运行环境
JVM的架构设计非常精妙,它确保了Java程序的跨平台性和高效执行。通过了解JVM的各个组件,我们可以更好地理解Java程序的运行机制,这对于编写高效且稳定的Java应用程序至关重要。
54 3
|
4月前
|
Java 测试技术 Android开发
Android项目架构设计问题之使用反射调用类的私有方法如何解决
Android项目架构设计问题之使用反射调用类的私有方法如何解决
39 0
|
5月前
软件复用问题之复用决策中,业务架构和技术之间有何关系
软件复用问题之复用决策中,业务架构和技术之间有何关系
|
5月前
业务系统架构实践问题之如何在biz层复用domain层的服务如何解决
业务系统架构实践问题之如何在biz层复用domain层的服务如何解决
|
6月前
|
缓存 NoSQL Java
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
案例 采用Springboot默认的缓存方案Simple在三层架构中完成一个手机验证码生成校验的程序
115 5
|
5月前
业务系统架构实践问题之实现平台集中复用和业务自主灵动的方式问题如何解决
业务系统架构实践问题之实现平台集中复用和业务自主灵动的方式问题如何解决
|
7月前
|
存储 设计模式 前端开发
请解释 Web 应用程序的 MVC(模型-视图-控制器)架构。
【2月更文挑战第26天】【2月更文挑战第89篇】请解释 Web 应用程序的 MVC(模型-视图-控制器)架构。
58 0