Newlife.XCode對象容器與接口操作實例


        本博客所有文章分類的總目錄:http://www.cnblogs.com/asxinyu/p/4288836.html

Newlife XCode組件相關文章目錄:http://www.cnblogs.com/asxinyu/p/4329747.html

1.前言

最近一個人狂看X組件的源碼,從CommonEntityXCode,然后XCoderXCode。感覺自己有很大的進步,視野更加開放,也能夠更加順手的做很多事情。

大石頭在5月份左右的時候,錄制了幾期視頻教程,其中有一期“使用對象容器來解耦業務模塊與管理平台”,對理解X組件很有好處,這期視頻我前后已經聽了4遍,當然每聽一遍都有一些新的發現與體會。今天要總結也是對象容器的一點理解以及為了解決問題,在XCoder源碼中發現的一些東西:接口操作。 

2.XCode對象容器介紹

 XCode對象容器的使用在XCode后台和Newlife.CommonEntity中有大量的使用,這也是后台很容易擴展的原因之一。只需要繼承相應的實體類(自動注冊優先級高於內部類),而基類中的代碼都是通過接口操作,這樣繼承的類就會優先被系統采用。 管理平台和業務平台通過接口和對象容器聯系起來。對象容器注冊接口的優先級: 

1.對象容器注冊優先采用配置文件中指定的接口 

2.配置文件里面沒找到之后,會去尋找所有的程序集,找到實現該接口的類,優先級僅次於配置文件。 

3.內部實現的類優先級要低,12都沒找到,就按默認的實現注冊順序采用。 

對象容器的注冊在靜態構造函數中,服務容器基類是泛型基類,這樣只要是繼承基類,然后加一個靜態構造函數,就可以在程序中給實現的接口的類進行注冊。 

上面是石頭的一些總結,聽起來可能不容易理解,下面舉一個例子,也算是昨天晚上研究了2個小時的成果吧。 

3.XCoder接口操作的實例 

XCoder代碼生成器中,可以將數據庫模型保存為XML文件,並可以直接加載XML文件進行模型的修改操作。但是其中有一些不便利。我想做一個直接添加模型的界面,這就涉及到一個問題,如何實例化一個IDataTable對象,查看XCoder的源碼發現了下面的東西: 

 1 private void btnAddTable_Click(object sender, EventArgs e)
 2         {
 3             if (Tables == null || Tables.Count < 1) return;
 4 
 5             Type type = Tables[0].GetType();
 6             if (type == null) return;
 7 
 8             IDataTable table = TypeX.CreateInstance(type) as IDataTable;
 9             if (table == null) return;
10 
11             Tables.Add(table);
12             table.ID = Tables.Count;
13             table.TableName = "NewTable" + table.ID;
14             table.Description = "新建表" + table.ID;
15 
16             SetTables(Tables, Tables.Count - 1);
17         }

 關鍵的代碼是:Type type = Tables[0].GetType();這里直接獲取當前數據庫中表的類型,然后:

和 IDataTable table = TypeX.CreateInstance(type) as IDataTable; 這里實體化一個接口,再進行賦值。

XCoder內部這樣做,是有優勢的。因為這是導入模型之后才進行的,導入模型的時候,默認實現IDataTable的類已經確定了,因為有對象容器,看XCodeService 

 1  /// <summary>XCode服務對象提供者</summary>
 2     class XCodeService : ServiceContainer<XCodeService>
 3     {
 4         static XCodeService()
 5         {
 6             var container = Container;
 7             container.Register<IDataTable, XTable>()
 8                 .AutoRegister<IDataRowEntityAccessorProvider, DataRowEntityAccessorProvider>()
 9                 .AutoRegister<IEntityPersistence, EntityPersistence>()
10                 .AutoRegister<IModelResolver, ModelResolver>();
11 
12             DbFactory.Reg(container);
13 
14             EntityAccessorFactory.Reg(container);
15         }        
28         #region 使用
29         /// <summary>創建模型數據表</summary>    
30         public static IDataTable CreateTable()
31         {
32             return Container.Resolve<IDataTable>();
33         }
34     }

  container.Register<IDataTable, XTable>();就是XCodeService在靜態構造函數中注冊IDataTable的默認實現類XTable,下面的使用方法CreateTable()就是返回一個IDataTable對象,然后在系統的其他地方就可以用XCodeService的這個CreateTable方法創建IDataTable對象了。

那么為什么最上面的代碼中,不這樣創建IDataTable對象呢?這里代碼太多了,只稍微說一下,因為第一段代碼這里已經是導入模型之后了,在導入模型過程中,已經確定了Tables的類型,代碼如下:

1 /// <summary>導入模型</summary>       
2         public static List<IDataTable> Import(String xml)
3         {
4             if (String.IsNullOrEmpty(xml)) return null;
5 
6             return ModelHelper.FromXml(xml, CreateTable);
7         }

這里的方法是DAL類中的,FromXML方法第二個參數是一個委托,這里傳入的CreateTable就是創建默認的IDataTable實例,看看他的代碼,很簡單,就是內部調用一次XCodeService的方法:

1  /// <summary>建立數據表對象</summary>
2         internal static IDataTable CreateTable() { return XCodeService.CreateTable(); }

到這里應該很清楚了,XCoder中操作對表的操作,都是通過IDataTable,而不設計具體的實現類,比如XTable,在外部程序中,你可以使用自己的Table類,實現IDataTable接口,這樣XCode內部會優先采用外部的實現類。

最后,說一下,這並沒有解決我的問題,在這里大家可能會注意到,XCodeService類是私有的,DALCreateTable方法是internal ,這樣外部程序集就沒辦法訪問得到。如果我要在外部程序中直接獲取一個IDataTable 對象,還的確辦不到,除非自己重寫一個IDataTable,但這樣又太麻煩,既然XCode有這樣的功能,不知道大石頭為什么不把DALCreateTable設為Public,是不是有什么其他考慮?


免責聲明!

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



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