您的位置:首页 > 运维架构 > 网站架构

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

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

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

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


结果是:

System.Int32

本示例使用静态方法 GetType(Object 基类派生的所有类型都继承该方法) 获取变量类型的简单反射实例

// Using Reflection to get information from an Assembly:
System.Reflection.Assembly o = System.Reflection.Assembly.Load("mscorlib.dll");
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中给出的类名生成相应的对象。

实现非常简单,根据容易名称去创建对象即可

/// <summary>
/// The static factory of container
/// </summary>
public sealed class ContainerManager
{
/// <summary>
/// Creates the specified container instance .
/// </summary>
/// <param name="containerName">Name of the container.</param>
/// <returns></returns>
public static IContainerContext GetContainer(string containerName)
{
return new UnityContainerContext(containerName);
}
}


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

/// <summary>
/// The specific container context for Unity
/// </summary>
public class UnityContainerContext : ContainerContextBase
{
#region Fields

/// <summary>
/// The lock used for synchronous
/// </summary>
private static readonly object _synlock = new object();

#endregion

#region Constructor

/// <summary>
/// Initializes a new instance of the <see cref="UnityContainerContext"/> class.
/// </summary>
/// <param name="name">The name.</param>
public UnityContainerContext(string name)
: base(name)
{
}

#endregion

#region Properties

/// <summary>
/// Gets the current context.
/// </summary>
/// <value>The current context.</value>
private HttpContext CurrentContext
{
get
{
HttpContext context = HttpContext.Current;
if (context == null)
{
throw new Exception("The current httpcontext is null");
}
return context;
}
}

#endregion

#region Override Methods

/// <summary>
/// Initializes container.
/// </summary>
public override void Initialize()
{
OnBeforeInitialized(new ContainerEventArgs(this, ContainerType.Unity));

if (CurrentContext.Application[Name] == null)
{
lock (_synlock)
{
if (CurrentContext.Application[Name] == null)
{
IUnityContainer currentContainer = new UnityContainer();
UnityConfigurationSection section = ConfigurationManager.GetSection("unity") as UnityConfigurationSection;
section.Containers[Name].Configure(currentContainer);
CurrentContext.Application[Name] = currentContainer;
}
}
}

OnAfterInitialized(new ContainerEventArgs(this, ContainerType.Unity));
}

/// <summary>
/// Resolves this instance.
/// </summary>
/// <typeparam name="T">Parameter type.</typeparam>
/// <returns></returns>
public override T Resolve<T>()
{
try
{
Initialize();

IUnityContainer currentContainer = CurrentContext.Application[Name] as IUnityContainer;
return currentContainer.Resolve<T>();
}
catch(Exception ex)
{
OnResolveFailed(new ContainerFailedEventArgs(this, ContainerType.Unity, ex));
return default(T);
}
}

/// <summary>
/// Tears down.
/// </summary>
public override void TearDown()
{
OnBeforeTearDown(new ContainerEventArgs(this, ContainerType.Unity));

CurrentContext.Application[Name] = null;

OnAfterTearDown(new ContainerEventArgs(this, ContainerType.Unity));
}

#endregion

}


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

/// <summary>
/// 数据层实体的个性操作对象
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <returns></returns>
protected TEntity LoadRepositoryEntity<TEntity>()
{
IContainerContext container = ContainerManager.GetContainer("repositoryContainer");
return container.Resolve<TEntity>();
}


这样,在BLL层调用DAL层对象时,可以通过LoadRepositoryEntity泛型方法来实现。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐