2012-09-29 35 views
3

我開始之前,讓我澄清任何疑惑纔有人提出或詢問的問題..的System.Reflection在Windows Mobile項目

這一問題與爲「Windows Mobile 6專業版」,而不是Windows手機7,它不能移植到Windows Phone 7上,因爲它必須繼續使用舊設備。

現在,有了這樣的方式......

目前,我試圖端口,我有來源的Windows Mobile 6設備上運行的C#庫,Iv'e這些編碼看起來像永遠的東西,但有一件事我們從未必須處理,直到現在,這就是反思。

現在大家都知道.NET Compact Framework確實有一些限制,並且似乎缺少對'System.Reflection'命名空間中的很多方法和屬性的支持是其中之一。

該庫的實際桌面版本設置爲以.NET V2.0爲目標,而且我的設備運行的是.NET 3.5 SP1,因此大多數情況下,Iv'e在使其工作時很少出現問題,一個不能然而似乎找到一個合理的得到以下2塊的代碼工作的:

 var a = AppDomain.CurrentDomain**.GetAssemblies**(); 
     foreach (var assembly in a) 
     { 
      if (assembly is System.Reflection**.Emit.**AssemblyBuilder) continue; 
      if (assembly**.GetType().**FullName == "System.Reflection.Emit.InternalAssemblyBuilder") continue; 
      if (assembly**.GlobalAssemblyCache** && assembly**.CodeBase** == Assembly.GetExecutingAssembly()**.CodeBase**) continue; 

      foreach (var t in GetLoadableTypes(assembly)) 
      { 
       if (t.IsInterface) continue; 
       if (t.IsAbstract) continue; 
       if (t.IsNotPublic) continue; 
       if (!typeof(IGeometryServices).IsAssignableFrom(t)) continue; 

       var constuctors = t.GetConstructors(); 
       foreach (var constructorInfo in constuctors) 
       { 
        if (constructorInfo.IsPublic && constructorInfo.GetParameters().Length == 0) 
         return (IGeometryServices)Activator.CreateInstance(t); 
       } 
      } 
     } 

而且

 catch (**ReflectionTypeLoadException** ex) 
     { 
      var types = ex**.Types**; 
      IList<Type> list = new List<Type>(types**.Length**); 
      foreach (var t in types) 
       if (t != null && t**.IsPublic**) 
        list.Add(t); 
      return list; 
     } 

具體來說,在大膽的項目在上面的代碼是方法和屬性,唐似乎沒有出現在緊湊的框架中,並花費了q在智能感知和對象瀏覽器方面需要大量的時間,否則我們不會找到任何返回(或提供)相同類型的東西。然後

我的問題如下:

沒有任何人有在緊湊型NET框架使用反射的任何經驗,可以建議該程序是如何能夠進行按預期方式工作,還是我將不得不開始編寫自定義存根和功能來替換缺失的方法。

我知道這個框架有一些反射功能,所以我確定必須有一種實現它的等效方式。

只是在最後的筆記上,對於任何可能識別代碼的人來說。是的,它來自.NET拓撲套件,是的,它是我正在試圖建立一個WM6版本的庫,所以如果你知道任何已經做過它的人,請對此做出評論,而我我們來看看更簡單的路徑:-)

================================= =====================================發佈

更新看起來'粗體'文本在代碼片段中不起作用,因此上面代碼中被**包圍的那些方法/屬性是應該以粗體顯示的部分。

+0

顯然,我的反射比你低。這裏到底發生了什麼?你想從COM對象訪問屬性嗎? – jp2code

+0

我也不太明白你在想什麼。如果您正在尋找一種方法來在不同的「平臺」上加載具有相同接口的不同程序集,您可以查看PocketMEF(託管可擴展框架)。它在codepley的源代碼中提供。 – josef

+0

看起來他們試圖從任何導出IGeometry接口類型的東西中創建具體的幾何類。請注意,我沒有寫這段代碼,我只負責將它移植到.NET CF中,因此我只想知道在沒有可用的標記屬性/方法的情況下實現這裏所發生的事情的最佳方式。 – shawty

回答

1

因此,研究後,一些較舊的建立和實驗的Silverlight版本(這顯然有很大作爲的Windows Mobile/CE相同的限制)

我想通了如何使魔的工作。

第一部分是用表示要搜索的程序集的'Assembly'結構填充數組。最初它是:

var a = AppDomain.CurrentDomain.GetAssemblies(); 

但由於GetAssemblies不存在WM然後最快的方法是使用下面的:

var a = new[] {Assembly.GetCallingAssembly(), Assembly.GetExecutingAssembly()}; 

現在在我的情況下,這意味着我得到了兩個相同的程序集,但如果我從我的主exe文件中調用Assembly,而後者又使用GeoAPI,那麼將在這裏顯示2個不同的程序集。

下一個挑戰是,我們並不需要檢查組件的「剝出」:

if (assembly is System.Reflection.Emit.AssemblyBuilder) continue; 

if (assembly.GetType().FullName == System.Reflection.Emit.InternalAssemblyBuilder") continue; 

if (assembly.GlobalAssemblyCache && assembly.CodeBase == Assembly.GetExecutingAssembly().CodeBase) continue; 

第一和第二實例從未在WM6突然出現,因此是安全的,只是把它們註釋掉。第二個是有用的,但是因爲你再也看不到任何帶有給定支票名稱的組件(由於它缺失),所以你應該安全地將它註釋掉。我沒有對此發表評論,但也從未被觸發過。

最後一部分(至少只要原始的益智還是去了)是這樣的:但是

foreach (var t in GetLoadableTypes(assembly)) 
{ 
    if (t.IsInterface) continue; 
    if (t.IsAbstract) continue; 
    if (t.IsNotPublic) continue; 
    if (!typeof(IGeometryServices).IsAssignableFrom(t)) continue; 

在我最初的嘗試「isInterface」 &「isNotPublic」,其中丟失,一旦我設法修正了上面'var''變量的內容與它所期望的數據類型,所有事情都開始正常工作,沒有遺漏任何東西。

最後一個問題是?這是否解決了一切?那麼不太....

事實證明,在GeoAPI的「ReflectInstance」方法的整個目的是尋找定義的「GeometryFactory」使用「IGeometryServices」界面的用戶。

由於我只反射在我是從(VAR一個以上)調用組件那麼「NetTopologySuite」(當幾何工廠定義的)不加入到選擇列表(顯然CurrentDomain.GetAssemblies包括這)

最終的結果是我仍然最終在最後碰到異常,因爲沒有找到正確類型的組件。

事實證明,但是,在「幾何」在GeoAPI構造具有過載,使您可以在GeometryFactory傳球,當你做到這一點完全忽略了ReflectInstance方法,只是用什麼它告訴。或者換句話說,我從來不需要做任何這樣的事情,我可以設置方法返回'null'並傳入我想要使用的幾何工廠。

無論如何,如果有人有興趣我現在有一個工作副本:

GeoAPI.NET NetTopologySuite Wintellect.PowerCollections

下的Windows Mobile 6和Windows CE .NET與CF內置和工作正常3.5。