高內聚,低耦合成爲一個OO架構設計的一個參考標準。高內聚是一個模塊或者一個類中成員跟這個模塊或者類的關係儘可能高,低耦合是不一樣模塊或者不一樣類之間關係儘可能簡單。html
拿咱國家舉例來講,假如你是中國人。編程
高內聚:就是說你跟中國親,關係好,國家會保護你。設計模式
低內聚:就是說你跟中國的關係很差,那還怎麼混,改天就要批鬥你,你就是個問題源。緩存
低耦合:就是說你跟日本的關係很是正常,很是簡單,這樣的話,就不會被罵漢奸了。session
高耦合:就是說你跟日本親,活該被砸,被遊街。架構
上面例子虛構的,不太貼切,但從中能夠看出來高內聚和低耦合的處境是最好的。高內聚是對內部成員跟自己這個模塊的關係的描述,低耦合是對成員跟外部模塊之間關係的描述。對內對外也是一個相對範圍,一個模塊裏面的小模塊之間是耦合,對大模塊是聚合,因此說耦合無處不在,咱們都要低耦合,Untity就能夠幫助咱們。app
Unity是一個IoC容器,用來實現依賴注入(Dependency Injection,DI),減小耦合的,Unity出自於偉大的微軟。對依賴注入和IoC模式能夠查看以前一篇文章IoC模式。
unity組件網址:http://unity.codeplex.com/
網址中有源碼有文檔有示例,你們能夠下載。我是用的是2.1版本。ide
看看Unity能作些什麼,列舉部分以下:函數
1.Unity支持簡單對象建立,特別是分層對象結構和依賴,以簡化程序代碼。其包含一個編譯那些可能存在依賴於其餘對象的對象實例機制。 ..... |
咱們項目中何時要使用到Unity呢,以下狀況:
1.所構建的系統依賴於健全的面向對象原則,可是大量不一樣的代碼交織在一塊兒而難以維護。 .............. |
先看看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使用方式基本分爲三步:
看到IUnityContainer接口聲明仍是比較簡單的,主要用到的方法也很少,另外提供了擴展方法,看起來代碼挺多,都是一些方法重載,不要對Unity組建感到恐懼,咱們只是簡單的使用它,主要是使用IUnityContainer。