我的開發框架(WinForm)3


今天繼續給大家介紹核心庫的IOC的使用,在我的框架里,IOC使用的比較簡單,主要是用於解除模塊間的耦合和實例化接口。

1、接口說明,IocContainer接口比較簡單只有3個方法,但是是系統中用的最多的。

IocContainer

 

2、接口的實現。我用的是AutoFac,選用他基於2個方面的考慮,第一是對MEf和泛型的支持,第二是效率

image

園子里的Leepy 已經對比過主流的IOC框架,http://www.cnblogs.com/liping13599168/archive/2011/07/17/2108734.html

時間比較早了,有興趣的可以用最新的類庫測試一下。

AutoFac有對MEF的擴展插件,很方便。這樣做的好處是,我可以只在核心模塊中引用AutoFac ,業務模塊中無需引用,用Mef標示即可,對於團隊開發來說,他無需再了解AutoFac如何使用。

不多說了,上代碼

    ContainerBuilder builder;
        IContainer _container = null;
        public AutofacContainer(params ComposablePartCatalog[] catalogs)
        {
            builder = new ContainerBuilder();

            bool isRegisterOrm = false;
            foreach (var item in catalogs)
            {
                builder.RegisterComposablePartCatalog(item);
                
                if (item is DirectoryCatalog && !isRegisterOrm)
                {
                    DirectoryCatalog dir=item as DirectoryCatalog;
                }
            }
           
        }

其中ComposablePartCatalog 是MEF的東東,ContainerBuilder 是AutoFac的東西, 這一步主要是講Mef的組件注冊到AutoFac里。然后通過 IContainer Container=builder.Build(Autofac.Builder.ContainerBuildOptions.IgnoreStartableComponents); 這個方法初始化完成,我測試的時候發現這個方法,只能執行一次,第二次就報錯。對應IocContainer.GetInstance 這個方法的實現就簡單了,調用Autofac的對應的方法就行了bool bl = Container.TryResolve<T>(out t);返回t 就OK了,

 
 

需要注意的是,Mef對泛型支持的不太好,所以需要單獨處理。

對於IRepository<T>和IRepository<T,Tid>接口來說,最理想的的情況是,我需要處理哪個實體類,就直接用var rep=  IocContainer.GetInstance<IRepository<T>>() 這種方式,就能到IRepository<T>的實例,然后進行后面的操作了。

首先獲得加載文件的所有 Assembly,然后判斷他的名字是否以"Repository`1"結尾,然后調用AutoFac的泛型注冊方法,注冊,

Assembly ass = Assembly.LoadFile(filepath);
Type[] types = ass.GetTypes().Where(t => t.Name.EndsWith("Repository`1")).ToArray();
if (types.Length > 0 && types[0].Name != "IRepository`1")
{
builder.RegisterGeneric(types[0]).As(typeof(IRepository<>));
isload = true;
}
由於本人對Autofac 也是一知半解,只能用笨辦法,肯定有好的辦法,只是我還不知道.望園子里的高手指點一下。
通過IocContainer接口,我們就可以創建並使用所有的接口了。
3、使用
   在Core中我設計了一個全局靜態類ApplicationEx,把IocContainer接口作為一個只讀屬性暴露出來,接口的實例化操作都在ApplicationEx的初始化中完成,在其他啟動的時候,初始化ApplicationEx一次,保證IOC被初始化一次,后面所有模塊的直接使用ApplicationEx的Container屬性。這就達到了我們想要的目的。
4、擴展
我是一個比較懶的人,不想每次都寫var rep=  IocContainer.GetInstance<IRepository<T>>() ,覺得寫得有點多
然后在Core里給IocContainer 增加了個擴展方法,
 /// <summary>
        /// 獲得數據操作倉庫接口
        /// </summary>
        /// <typeparam name="T">操作的實體類</typeparam>
        /// <returns>IRepository{``0}.</returns>
        public static IRepository<T> GetRepository<T>(this IocContainer ioc) where T : EntityBase, new()
        {
            return ioc.GetInstance<IRepository<T>>();
        }

以后所有的模塊調用就直接寫var rep=  IocContainer.GetRepository<T>(),又少寫了10幾個字符,呵呵呵。

今天就到這里吧,后面接着給大家介紹。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM