zoukankan      html  css  js  c++  java
  • 架构,改善程序复用性的设计~第五讲 复用离不开反射和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泛型方法来实现。

  • 相关阅读:
    callAfter 例子2
    wxpython
    python 处理excel 进程无法退出的问题
    常用电子技术网
    Emeditor 与正则表达式
    Windows程序中的字符编码
    Delphi7 无法启动 问题搞定
    2007中国发烧盘点之作《天路》发烧女声版
    一台电脑安装多个(虚拟)网卡问题
    无法删除xxx文档/文件夹:找不到指定的路径。请确定指定的路径是否正确
  • 原文地址:https://www.cnblogs.com/lori/p/2532695.html
Copyright © 2011-2022 走看看