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 接口的定义:

  1. //Interface defining the behavior of the Unity dependency injection container.
  2. public interface IUnityContainer : IDisposable
  3. {
  4. //The parent of this container.
  5. IUnityContainer Parent { get; }
  6.  
  7. //Get a sequence of Microsoft.Practices.Unity.ContainerRegistration that describe
  8. //the current state of the container.
  9. IEnumerable<ContainerRegistration> Registrations { get; }
  10.  
  11. //Add an extension object to the container.
  12. IUnityContainer AddExtension(UnityContainerExtension extension);
  13.  
  14. //Run an existing object through the container and perform injection on it.
  15. object BuildUp(Type t, object existing, string name, params ResolverOverride[] resolverOverrides);
  16.  
  17. //Resolve access to a configuration interface exposed by an extension.
  18. object Configure(Type configurationInterface);
  19.  
  20. //Create a child container.
  21. IUnityContainer CreateChildContainer();
  22.  
  23. //Register an instance with the container.
  24. IUnityContainer RegisterInstance(Type t, string name, object instance, LifetimeManager lifetime);
  25.  
  26. //Register a type mapping with the container, where the created instances will
  27. //use the given Microsoft.Practices.Unity.LifetimeManager.
  28. IUnityContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  29.  
  30. //Remove all installed extensions from this container.
  31. IUnityContainer RemoveAllExtensions();
  32.  
  33. //Resolve an instance of the requested type with the given name from the container.
  34. object Resolve(Type t, string name, params ResolverOverride[] resolverOverrides);
  35.  
  36. //Return instances of all registered types requested.
  37. IEnumerable<object> ResolveAll(Type t, params ResolverOverride[] resolverOverrides);
  38.  
  39. //Run an existing object through the container, and clean it up.
  40. void Teardown(object o);
  41. }

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

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

  1. /// <summary>
  2. /// 扩展方法 v2.0.50727
  3. /// </summary>
  4. public static class UnityContainerExtensions
  5. {
  6. public static IUnityContainer AddNewExtension<TExtension>(this IUnityContainer container) where TExtension : UnityContainerExtension;
  7. public static T BuildUp<T>(this IUnityContainer container, T existing, params ResolverOverride[] resolverOverrides);
  8. public static T BuildUp<T>(this IUnityContainer container, T existing, string name, params ResolverOverride[] resolverOverrides);
  9. public static object BuildUp(this IUnityContainer container, Type t, object existing, params ResolverOverride[] resolverOverrides);
  10. public static TConfigurator Configure<TConfigurator>(this IUnityContainer container) where TConfigurator : IUnityContainerExtensionConfigurator;
  11. public static bool IsRegistered<T>(this IUnityContainer container);
  12. public static bool IsRegistered<T>(this IUnityContainer container, string nameToCheck);
  13. public static bool IsRegistered(this IUnityContainer container, Type typeToCheck);
  14. public static bool IsRegistered(this IUnityContainer container, Type typeToCheck, string nameToCheck);
  15. public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, TInterface instance);
  16. public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, string name, TInterface instance);
  17. public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, TInterface instance, LifetimeManager lifetimeManager);
  18. public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, object instance);
  19. public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, string name, TInterface instance, LifetimeManager lifetimeManager);
  20. public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, object instance, LifetimeManager lifetimeManager);
  21. public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, string name, object instance);
  22. public static IUnityContainer RegisterType<T>(this IUnityContainer container, params InjectionMember[] injectionMembers);
  23. public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, params InjectionMember[] injectionMembers) where TTo : TFrom;
  24. public static IUnityContainer RegisterType<T>(this IUnityContainer container, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  25. public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom;
  26. public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, string name, params InjectionMember[] injectionMembers) where TTo : TFrom;
  27. public static IUnityContainer RegisterType<T>(this IUnityContainer container, string name, params InjectionMember[] injectionMembers);
  28. public static IUnityContainer RegisterType(this IUnityContainer container, Type t, params InjectionMember[] injectionMembers);
  29. public static IUnityContainer RegisterType<T>(this IUnityContainer container, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  30. public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom;
  31. public static IUnityContainer RegisterType(this IUnityContainer container, Type t, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  32. public static IUnityContainer RegisterType(this IUnityContainer container, Type t, string name, params InjectionMember[] injectionMembers);
  33. public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, params InjectionMember[] injectionMembers);
  34. public static IUnityContainer RegisterType(this IUnityContainer container, Type t, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  35. public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  36. public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, string name, params InjectionMember[] injectionMembers);
  37. public static T Resolve<T>(this IUnityContainer container, params ResolverOverride[] overrides);
  38. public static T Resolve<T>(this IUnityContainer container, string name, params ResolverOverride[] overrides);
  39. public static object Resolve(this IUnityContainer container, Type t, params ResolverOverride[] overrides);
  40. public static IEnumerable<T> ResolveAll<T>(this IUnityContainer container, params ResolverOverride[] resolverOverrides);
  41.  
  42. public static IUnityContainer LoadConfiguration(this IUnityContainer container);
  43. public static IUnityContainer LoadConfiguration(this IUnityContainer container, string containerName);
  44. public static IUnityContainer LoadConfiguration(this IUnityContainer container, UnityConfigurationSection section);
  45. public static IUnityContainer LoadConfiguration(this IUnityContainer container, UnityConfigurationSection section, string containerName);
  46. }

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

  1. /// <summary>
  2. /// 班级接口
  3. /// </summary>
  4. public interface IClass
  5. {
  6. string ClassName { get; set; }
  7.  
  8. void ShowInfo();
  9. }
  10. /// <summary>
  11. /// 计科班
  12. /// </summary>
  13. public class CbClass : IClass
  14. {
  15. public string ClassName { get; set; }
  16.  
  17. public void ShowInfo()
  18. {
  19. Console.WriteLine("计科班:{0}", ClassName);
  20. }
  21. }
  22. /// <summary>
  23. /// 电商班
  24. /// </summary>
  25. public class EcClass : IClass
  26. {
  27. public string ClassName { get; set; }
  28.  
  29. public void ShowInfo()
  30. {
  31. Console.WriteLine("电商班:{0}", ClassName);
  32. }
  33. }

用编程方式实现注入:

  1. public static void ContainerCodeTest1()
  2. {
  3. IUnityContainer container = new UnityContainer();
  4.  
  5. //默认注册(无命名),如果后面还有默认注册会覆盖前面的
  6. container.RegisterType<IClass, CbClass>();
  7.  
  8. //命名注册
  9. container.RegisterType<IClass, EcClass>("ec");
  10.  
  11. //解析默认对象
  12. IClass cbClass = container.Resolve<IClass>();
  13. cbClass.ShowInfo();
  14.  
  15. //指定命名解析对象
  16. IClass ecClass = container.Resolve<IClass>("ec");
  17. ecClass.ShowInfo();
  18.  
  19. //获取容器中所有IClass的注册的已命名对象
  20. IEnumerable<IClass> classList = container.ResolveAll<IClass>();
  21. foreach (var item in classList)
  22. {
  23. item.ShowInfo();
  24. }
  25. }

配置文件方式:

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

效果跟代码方式一样

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. hibernate学习(初识)

    hibernate是一个开源的对象关系映射框架(ORM).对JDBC进行了轻量级的封装.将对象和数据库表建立映射关系,hibernate框架使用在数据持久化层(DAO). ORM:对象关系映射(Obj ...

  2. 前端 CSS语法

    每个CSS样式由两个组成部分: 1.选择器 2.声明 声明由属性和值组成,每个声明之后用分号结束.

  3. 2018-2019-2 网络对抗技术 20165236 Exp3 免杀原理与实践

    2018-2019-2 网络对抗技术 20165236 Exp3 免杀原理与实践 一.实践内容(3.5分) 1.1 正确使用msf编码器(0.5分),msfvenom生成如jar之类的其他文件(0.5 ...

  4. Postman代码测试工具如何用?

    1.  1)get请求,参数为map时, postman的传参 2)参数为基本数据类型的参数时 postman传参: 3)当参数在接口中动态获取时 postman传参: 2.  1)post请求,参数 ...

  5. office word memo

    显示左侧目录树 office 和 wps 的差异 wps 的版本:视窗 ->文档结构图 office 的版本: 视图 ->导航窗格

  6. Vmworkstation启用错误

    无法打开内核设备"\\.\Global\vmx86":系统找不到指定的文件. 是否在安装 VMwareWorksation 后重新引到 ? 问题解决   无法连接 MKS:套接字连 ...

  7. 《linux就该这么学》第十七节课:第18,19,23章,mariadb数据库、PXE无人值守安装系统和openldap目录服务。

    第23章 (借鉴请改动) openldap数据的特点:1.短小.2.读取次数较多 上述说明: openLDAP服务端配置:     1.yum install -y openldap openldap ...

  8. POJ 1390 Blocks(区间DP)

    Blocks [题目链接]Blocks [题目类型]区间DP &题意: 给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值 &题解: 这 ...

  9. zookeeper注册与发现

    pom.xml添加如下引用: <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId ...

  10. vim中自动格式化代码

    1,gg 跳转到第一行 2,shift+v 转到可视模式 3,shift+g 全选 4,按下神奇的 =