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. python中字符串的拼接

    1.+ 号 2.format() 3.f"{username}登录成功" 4.%s 5.列表中的 join 6.逗号 http://www.cnblogs.com/gengcx/p ...

  2. webpack.config.js配置遇到Error: Cannot find module '@babel/core'&&Cannot find module '@babel/plugin-transform-react-jsx' 问题

    下文是网上找到的方法,是因为版本冲突的原因,参照后安装7版本解决 cnpm install -D babel-loader@ babel-core babel-preset-env 一. 问题描述 在 ...

  3. #20175201 实验二:Java面向对象程序设计

    20175201 实验二:Java面向对象程序设计 实验二 Java面向对象程序设计 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L ...

  4. #WEB安全基础 : HTTP协议 | 0x10 扩展HTTP报文结构概念和内容编码

    #以后的知识都是HTTP协议的扩展,如果精力有限可以选择暂时忽略,注意只是暂时忽略,以后的东西同样重要 HTTP传输数据时可以直接传输也可以对数据进行编码,由于编码在计算机内运行,所以会占用一些CPU ...

  5. cygwin 安装 apt-cyg

    apt-cyg apt-cyg is a Cygwin package manager. It includes a command-line installer for Cygwin which c ...

  6. JVM运行原理

    JVM运行原理

  7. 将文件转成clob添加到Oracle数据库中

    Controller层: @Controller@RequestMapping(value = {"/Test/TestController"})public class Test ...

  8. php魔术变量以及命名空间

    魔术变量: PHP 向它运行的任何脚本提供了大量的预定义常量. 不过很多常量都是由不同的扩展库定义的,只有在加载了这些扩展库时才会出现,或者动态加载后,或者在编译时已经包括进去了. 有八个魔术常量它们 ...

  9. Jenkins - ERROR: Exception when publishing, exception message [Failed to connect session for config [IP(projectName)]. Message [Auth fail]]

    今天在处理Jenkins的时候出现了一些异常,看着控制台,编译都是通过的,只是没有部署上来,查看了控制台日志,如下: 刚开始以为磁盘满了(参考:https://www.cnblogs.com/yuch ...

  10. FineUI 相关

    FineUI 相关(ExtAsp.Net 2008-2017),记在这把,免得找不到了. 不知道同年代的类似项目Coolite怎么样了?更名为Ext.net了,在国外活得还算滋润,在国内嘛..死贵死贵 ...