1.引言

高内聚,低耦合成为一个OO架构设计的一个参考标准。高内聚是一个模块或者一个类中成员跟这个模块或者类的关系尽量高,低耦合是不同模块或者不同类之间关系尽量简单。

拿咱国家举例来说,假如你是中国人。

高内聚:就是说你跟中国亲,关系好,国家会保护你。

低内聚:就是说你跟中国的关系不好,那还怎么混,改天就要批斗你,你就是个问题源。

低耦合:就是说你跟日本的关系非常正常,非常简单,这样的话,就不会被骂汉奸了。

高耦合:就是说你跟日本亲,活该被砸,被游街。

上面例子虚构的,不太贴切,但从中可以看出来高内聚和低耦合的处境是最好的。高内聚是对内部成员跟本身这个模块的关系的描述,低耦合是对成员跟外部模块之间关系的描述。对内对外也是一个相对范围,一个模块里面的小模块之间是耦合,对大模块是聚合,所以说耦合无处不在,我们都要低耦合,Untity就可以帮助我们。

2.Unity

Unity是一个IoC容器,用来实现依赖注入(Dependency Injection,DI),减少耦合的,Unity出自于伟大的微软。对依赖注入和IoC模式可以查看之前一篇文章IoC模式
unity组件网址:http://unity.codeplex.com/
网址中有源码有文档有示例,大家可以下载。我是用的是2.1版本。

看看Unity能做些什么,列举部分如下:

1.Unity支持简单对象创建,特别是分层对象结构和依赖,以简化程序代码。其包含一个编译那些可能存在依赖于其他对象的对象实例机制。
2.Unity支持必要的抽象,其允许开发者在运行时或配置去指定依赖关系同时可以简单的管理横切点(AOP)。
3.Unity增加了推迟到容器组件配置的灵活性。其同样支持一个容器层次的结构。
4.Unity拥有服务定位能力,对于一个程序在许多情况下重复使用组件来分离和集中功能是非常有用的。
5.Unity允许客户端储存或缓存容器。对于在ASP.NET Web applications中开发者将容器持久化于ASP.NET中的session或application中特别有效。
6.Unity拥有拦截能力,其允许开发者通过创建并执行handlers(在方法或属性被调用到达之前)来为已存在的组件增加一个函数,并再次为返回调用结果。
7.Unity可以从标准配置系统中读取配置信息,例如:XML文件,同时使用配置文件来配置容器。
8.Unity支持开发者实现自定义容器扩展,例如:你可以实现方法来允许额外的对象构造和容器特征,例如缓存。
9.Unity允许架构师和开发者在现代化的程序中更简单的实现通用设计模式。

.....

我们项目中什么时候要使用到Unity呢,如下情况:

1.所构建的系统依赖于健全的面向对象原则,但是大量不同的代码交织在一起而难以维护。
2.构建的对象和类需要依赖其他对象或类。
3.依赖于复杂的或需要抽象的对象。
4.希望利用构造函数、方法或属性的调用注入优势。
5.希望管理对象实例的生命周期。
6.希望能够在运行时管理并改变依赖关系。
7.希望在拦截方法或属性调用的时候生成一个策略链或管道处理容器来实现横切(AOP)任务。
8.希望在Web Application中的回发操作时能够缓存或持久化依赖关系。

..............

先看看Unity容器IUnityContainer 接口的定义:

    //Interface defining the behavior of the Unity dependency injection container.
public interface IUnityContainer : IDisposable
{
//The parent of this container.
IUnityContainer Parent { get; } //Get a sequence of Microsoft.Practices.Unity.ContainerRegistration that describe
//the current state of the container.
IEnumerable<ContainerRegistration> Registrations { get; } //Add an extension object to the container.
IUnityContainer AddExtension(UnityContainerExtension extension); //Run an existing object through the container and perform injection on it.
object BuildUp(Type t, object existing, string name, params ResolverOverride[] resolverOverrides); //Resolve access to a configuration interface exposed by an extension.
object Configure(Type configurationInterface); //Create a child container.
IUnityContainer CreateChildContainer(); //Register an instance with the container.
IUnityContainer RegisterInstance(Type t, string name, object instance, LifetimeManager lifetime); //Register a type mapping with the container, where the created instances will
//use the given Microsoft.Practices.Unity.LifetimeManager.
IUnityContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers); //Remove all installed extensions from this container.
IUnityContainer RemoveAllExtensions(); //Resolve an instance of the requested type with the given name from the container.
object Resolve(Type t, string name, params ResolverOverride[] resolverOverrides); //Return instances of all registered types requested.
IEnumerable<object> ResolveAll(Type t, params ResolverOverride[] resolverOverrides); //Run an existing object through the container, and clean it up.
void Teardown(object o);
}

IUnityContainer 中有几个方法经常会使用到,如:RegisterInstance,RegisterType,Resolve等等。

Unity为了方便操作,专门为IUnityContainer 提供了许多的扩展方法,部分方法声明如:

    /// <summary>
/// 扩展方法 v2.0.50727
/// </summary>
public static class UnityContainerExtensions
{
public static IUnityContainer AddNewExtension<TExtension>(this IUnityContainer container) where TExtension : UnityContainerExtension;
public static T BuildUp<T>(this IUnityContainer container, T existing, params ResolverOverride[] resolverOverrides);
public static T BuildUp<T>(this IUnityContainer container, T existing, string name, params ResolverOverride[] resolverOverrides);
public static object BuildUp(this IUnityContainer container, Type t, object existing, params ResolverOverride[] resolverOverrides);
public static TConfigurator Configure<TConfigurator>(this IUnityContainer container) where TConfigurator : IUnityContainerExtensionConfigurator;
public static bool IsRegistered<T>(this IUnityContainer container);
public static bool IsRegistered<T>(this IUnityContainer container, string nameToCheck);
public static bool IsRegistered(this IUnityContainer container, Type typeToCheck);
public static bool IsRegistered(this IUnityContainer container, Type typeToCheck, string nameToCheck);
public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, TInterface instance);
public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, string name, TInterface instance);
public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, TInterface instance, LifetimeManager lifetimeManager);
public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, object instance);
public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, string name, TInterface instance, LifetimeManager lifetimeManager);
public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, object instance, LifetimeManager lifetimeManager);
public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, string name, object instance);
public static IUnityContainer RegisterType<T>(this IUnityContainer container, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, params InjectionMember[] injectionMembers) where TTo : TFrom;
public static IUnityContainer RegisterType<T>(this IUnityContainer container, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom;
public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, string name, params InjectionMember[] injectionMembers) where TTo : TFrom;
public static IUnityContainer RegisterType<T>(this IUnityContainer container, string name, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType(this IUnityContainer container, Type t, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType<T>(this IUnityContainer container, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom;
public static IUnityContainer RegisterType(this IUnityContainer container, Type t, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType(this IUnityContainer container, Type t, string name, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType(this IUnityContainer container, Type t, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, string name, params InjectionMember[] injectionMembers);
public static T Resolve<T>(this IUnityContainer container, params ResolverOverride[] overrides);
public static T Resolve<T>(this IUnityContainer container, string name, params ResolverOverride[] overrides);
public static object Resolve(this IUnityContainer container, Type t, params ResolverOverride[] overrides);
public static IEnumerable<T> ResolveAll<T>(this IUnityContainer container, params ResolverOverride[] resolverOverrides); public static IUnityContainer LoadConfiguration(this IUnityContainer container);
public static IUnityContainer LoadConfiguration(this IUnityContainer container, string containerName);
public static IUnityContainer LoadConfiguration(this IUnityContainer container, UnityConfigurationSection section);
public static IUnityContainer LoadConfiguration(this IUnityContainer container, UnityConfigurationSection section, string containerName);
}

下面来个简单的例子,现在项目中添加Microsoft.Practices.Unity.dll和Microsoft.Practices.Unity.Configuration.dll的引用,准备几个类,如下:

    /// <summary>
/// 班级接口
/// </summary>
public interface IClass
{
string ClassName { get; set; } void ShowInfo();
}
/// <summary>
/// 计科班
/// </summary>
public class CbClass : IClass
{
public string ClassName { get; set; } public void ShowInfo()
{
Console.WriteLine("计科班:{0}", ClassName);
}
}
/// <summary>
/// 电商班
/// </summary>
public class EcClass : IClass
{
public string ClassName { get; set; } public void ShowInfo()
{
Console.WriteLine("电商班:{0}", ClassName);
}
}

用编程方式实现注入:

        public static void ContainerCodeTest1()
{
IUnityContainer container = new UnityContainer(); //默认注册(无命名),如果后面还有默认注册会覆盖前面的
container.RegisterType<IClass, CbClass>(); //命名注册
container.RegisterType<IClass, EcClass>("ec"); //解析默认对象
IClass cbClass = container.Resolve<IClass>();
cbClass.ShowInfo(); //指定命名解析对象
IClass ecClass = container.Resolve<IClass>("ec");
ecClass.ShowInfo(); //获取容器中所有IClass的注册的已命名对象
IEnumerable<IClass> classList = container.ResolveAll<IClass>();
foreach (var item in classList)
{
item.ShowInfo();
}
}

配置文件方式:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,Microsoft.Practices.Unity.Configuration"/>
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<!--定义类型别名-->
<aliases>
<add alias="IClass" type="ConsoleApplication1.UnityDemo.IClass,ConsoleApplication1" />
<add alias="CbClass" type="ConsoleApplication1.UnityDemo.CbClass,ConsoleApplication1" />
<add alias="EcClass" type="ConsoleApplication1.UnityDemo.EcClass,ConsoleApplication1" />
</aliases>
<!--容器-->
<container name="FirstClass">
<!--映射关系-->
<register type="IClass" mapTo="CbClass"></register>
<register type="IClass" name="ec" mapTo="EcClass"></register>
</container>
</unity>
</configuration>
        public static void ContainerConfigurationTest1()
{
IUnityContainer container = new UnityContainer();
string configFile = "http://www.cnblogs.com/UnityDemo/Constructor/Unity.config";
var fileMap = new ExeConfigurationFileMap { ExeConfigFilename = configFile };
//从config文件中读取配置信息
Configuration configuration =
ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
//获取指定名称的配置节
UnityConfigurationSection section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity"); //载入名称为FirstClass 的container节点
container.LoadConfiguration(section, "FirstClass"); //解析默认对象
IClass cbClass = container.Resolve<IClass>();
cbClass.ShowInfo(); //指定命名解析对象
IClass ecClass = container.Resolve<IClass>("ec");
ecClass.ShowInfo(); //获取容器中所有IClass的注册的已命名对象
IEnumerable<IClass> classList = container.ResolveAll<IClass>();
foreach (var item in classList)
{
item.ShowInfo();
}
}

效果跟代码方式一样

Unity使用方式基本分为三步:

  1. 声明容器IUnityContainer
  2. Register注册类型
  3. Resolve解析类型对象

3.小结

看到IUnityContainer接口声明还是比较简单的,主要用到的方法也不多,另外提供了扩展方法,看起来代码挺多,都是一些方法重载,不要对Unity组建感到恐惧,我们只是简单的使用它,主要是使用IUnityContainer。

[IoC容器Unity]第一回:Unity预览的更多相关文章

  1. Power Pivot表属性无法切换回表预览模式的问题

    近期Office365用户升级后解决了在Power Pivot中输入中文的问题,但是同时也带来了一个新的问题就是表属性窗口默认为“查询编辑器”模式,且无法切换回“表预览”模式. 本文和您分享在这种情况 ...

  2. 微软发布Azure Stack第一个技术预览版

    为了提升商业灵敏度和加快创新步伐,各个企业都在迅速地转向云服务.在微软,我们已经见到微软智能云Azure的飞速发展和使用,每月我们都有近十万的新增订阅量.然而,我们也了解到还有很多企业在完全移到公有云 ...

  3. Unity 摄像头竖屏预览显示的问题

    Unity可以通过WebCamTexture打开摄像头,通过 cameraRawImage.texture = camTexture; 将贴图给RawImage,但是WebCamTexture只能设置 ...

  4. [IoC容器Unity]第四回:使用范例

    1.引言 前面几个章节介绍了Unity的基本使用,主要分为程序和配置文件两种方法的使用,可以参考一下链接, [IoC容器Unity]第一回:Unity预览 [IoC容器Unity]第二回:Lifeti ...

  5. 9种CSS3炫酷图片展开预览展示动画特效

    详细内容请点击 在线预览立即下载 这是一组共9款CSS3炫酷图片预览展示动画特效插件.css的新特性可以让我们制作出各种炫酷的动画效果.该图片预览展示动画特效就是一个很好的例子,该效果开始时图片堆叠在 ...

  6. iOS开发之使用Storyboard预览UI在不同屏幕上的运行效果

    在公司做项目一直使用Storyboard,虽然有时会遇到团队合作的Storyboard冲突问题,但是对于Storyboard开发效率之高还是比较划算的.在之前的博客中也提到过,团队合作使用Storyb ...

  7. Spring框架学习[IoC容器高级特性]

    1.通过前面4篇文章对Spring IoC容器的源码分析,我们已经基本上了解了Spring IoC容器对Bean定义资源的定位.读入和解析过程,同时也清楚了当用户通过getBean方法向IoC容器获取 ...

  8. 新的理念、 新的解决方案、 新的Azure Stack技术预览

    Jeffrey Snover 我们很高兴地宣布︰Azure Stack Technical Preview 2(TP2)已发布!我们朝着向您的数据中心提供Azure服务能力的目标又更近一步.自发布第一 ...

  9. Android 10开发者预览版功能介绍

    Android P的开发者预览版最亮眼的功能莫过于支持“刘海屏”等屏幕显示.同样在适配可折叠设备方面,Android Q的第一个开发者预览版也很“接地气”,谷歌早在去年11月就发布了对可折叠设备的支持 ...

随机推荐

  1. pkg-config 详解

    转载自:https://blog.csdn.net/newchenxf/article/details/51750239 1 什么是pkg-config pkg-config是一个linux下的命令, ...

  2. JavaWeb学习之三层架构实例(二)

    引言 这个实例是上一个实例JavaWeb学习 三层架构实例(一)的加强版,实现的是在前端对数据库中student表的 增.删.改.查 操作.关于三层组成云云,这里就不再叙述. 实例 效果图 先来看一下 ...

  3. 兼容不同浏览器的CSS前缀-webkit-,-ms-,-moz-,-o-

    笔者在工作实践中发现当需要CSS兼容不同的浏览器时,需要在CSS样式前加上不同的前缀,从而使其他浏览器也能够达到相同的页面效果. 那么我们怎么去加上这些前缀呢?我们一起带着疑问来进行学习: 1.前缀分 ...

  4. 使用Java代码发送邮件

  5. Python类__call__()方法

    在python中,创建类型的时候定义了__call__()方法,那这个类型创建出来的实例就是可调用的.例def如: class A(object): def __init__(self,name,ag ...

  6. pycharm Python Console调试 & django 调试

    1.设置断点,然后debug     2.如果在运行中想修改变量,可以直接在pycharm中修改 如将列表的 13改成3,然后选中 Excuting Selection in console     ...

  7. caffe 环境搭建

    1.VS安装 VS社区版(个人免费): http://download.microsoft.com/download/B/4/8/B4870509-05CB-447C-878F-2F80E4CB464 ...

  8. 005-CSS让页脚始终在底部不论页面内容多少

    让页脚始终在页面底部,不论页面内容是多或者少页脚始终在页面底部. 方案一: <!DOCTYPE html> <html> <head> <meta chars ...

  9. 数据迁移时 提示 No changes detected

    1.删除数据库中django_migrations 中对应的信息 2.删除app下的migrations对应的文件 3.重新执行就可成功 如不成功 ,直接删库 ,重新迁移

  10. android 开发设计模式---Builder模式

    我们通过一个例子来引出Builder模式.假设有一个Person类,我们通过该Person类来构建一大批人,这个Person类里有很多属性,最常见的比如name,age,weight,height等等 ...