文章出處

回到目錄

之前的一篇Unity的文章主要是基本的實現,并沒有什么特別的地方,使用Unity可以方便的實現應用程序的IoC控制反轉,這給我們的應用程序在耦合度上變得高了,同時可測試性加強了,當然,這些的前提都是面向接口編程,如果你面向了具體實現去寫程序,那你不用再看本篇文章了,呵呵。

本文章主要分享一下,通過Unity組件里的服務定位器ServiceLocator來實現批量加載類型,即你不用那它們一個個的配置到config文件里了,甚至在進行動態加載時,同時可以為它添加一些行為,如緩存,呵呵 !

下面說一下實現思想

首先unity有自己的容易UnityContainer,我們的配置信息都是向它里面添加的,它公開了RegisterType方法,用來向容器里注冊類型和行為(aop),我們就是通過這個方法將應用程序的bin目錄下的指定dll里的所有接口實現類進行提取,并添加到UnityContainer容器里,這樣就實現了批量的動態的注冊類型!

我的project.Ioc項目結構(來自倉儲大叔框架集)

修改ServiceLocator文件的內容

添加了指定的私有方法來干這事

        /// <summary>
        /// 裝載一批動態的類型
        /// Author:zhangzhanling
        /// Date:2015-04-03
        /// </summary>
        private void LoadDynamicType(IUnityContainer _container)
        {
            //unity動態類型注入,各個程序集用,分開,支持*通配符號
            string unityDynamicAssembly = System.Configuration.ConfigurationManager.AppSettings["unityDynamicAssembly"];
            //是否同時啟動數據集緩存策略
            string unityCachingDoing = System.Configuration.ConfigurationManager.AppSettings["unityCachingDoing"];
            InjectionMember[] injectionMembers = null;
            if (unityCachingDoing == "1")
            {
                injectionMembers = new InjectionMember[] { new Interceptor<InterfaceInterceptor>(), new InterceptionBehavior<Project.UnityCaching.CachingBehavior>() };
            }
            if (!string.IsNullOrWhiteSpace(unityDynamicAssembly))
            {
                Array.ForEach(unityDynamicAssembly.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries), dllName =>
                {
                    var baseDir = AppDomain.CurrentDomain.BaseDirectory;
                    if (System.Web.HttpContext.Current != null)
                    {
                        baseDir += "bin";
                    }
                    var files = Directory.GetFiles(baseDir, dllName);
                    var iTypes = new List<Type>();
                    foreach (var file in files)
                    {
                        var interfaceASM = Assembly.LoadFrom(Path.Combine(baseDir, file));
                        var types = from t in interfaceASM.GetTypes()
                                    where !string.IsNullOrWhiteSpace(t.Namespace)
                                    select t;

                        foreach (var type in types)
                        {
                            if (type.GetInterfaces() != null && type.GetInterfaces().Any())
                                foreach (var father in type.GetInterfaces())
                                {
                                    _container.RegisterType(father
                                        , type
                                        , injectionMembers);
                                }
                        }
                    }
                });

            }

        }

ServiceLocator中調用它

大功告成了,哈哈!

回到目錄


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()