2012-02-08 47 views
37

我從兩個不同的第三方COM DLL創建了兩個.NET Interop程序集。這兩個COM DLL都包含一個名爲COMMONTYPE的類型。因此,COMMONTYPE現在也通過兩個Interop程序集公開。類型存在於2個程序集中

我的第三個項目,需要使用這兩個互操作程序集,我也得到了臭名昭著的編譯時錯誤:

The type <ABC> exists in both <ASSEMBLY1.dll> and <ASSEMBLY2.dll>

由於是由第三方供應商提供的COM DLL文件,我沒有訪問源代碼,我正在編寫一個C#控制檯應用程序,這意味着我沒有web.config文件,我可以在其中添加debug=false解決方法。我能做什麼?

+0

我來到這裏是因爲Visual Studio中被抱怨JsonConvert中都存在Newtonsoft類型。 Json.Torq和Newtonsoft.Json – Matthew 2017-12-20 00:38:50

回答

0

也許你可以欺騙它,通過改變組件之一的namespace,在這種情況下,一個COMMONTYPE的完全合格的名稱將不等於彼此,可能它可以解決衝突發生在你的問題第三個DLL。

希望這會有所幫助。

+0

不幸的是,我不能這樣做因爲我使用tlbimp從現有的COM DLL生成.NET程序集。 – 2012-02-09 08:58:14

11

除非供應商的命名空間是相同的(不太可能),否則類型定義實際上在此時是分開的。你需要做的事(有時候這是一個完整的PITA)是在你的using語句中創建一個名稱空間別名,而不是簡單地應用語句carte blanche。這將讓你重新標識命名空間:

using Vendor1 = Vendor.Namespace; 
using Vendor2 = OtherVendor.Namespace; 

... 

Vendor1.COMMONTYPE blah = new Vendor1.COMMONTYPE(); 
Vendor2.COMMONTYPE blah2 = new Vendor2.COMMONTYPE(); 

這將意味着使用位於每個命名空間爲這些供應商的所有類型的特定別名。

+0

感謝Joel的回覆。 – 2012-02-09 06:56:06

+0

這肯定會幫助我解決編譯時錯誤。 但是我沒有辦法讓.NET在創建程序集的時候忽略特定的類型,這樣我就只有一個程序集中有公共類型。 – 2012-02-09 08:31:41

+0

@KouSHal:唯一的方法是構建一個引用供應商庫之一的包裝類,並將所有類,擴展方法等作爲代理公開。如果它只有少數幾個類的小型圖書館,這不會太難,但如果它像大多數供應商的圖書館一樣,這將是一個噩夢,創造和惡化維護。 – 2012-02-09 11:07:53

1

您可以使用別名來了不同的命名空間和/或類型:

這裏是它會是什麼樣子:

using other = sssssss.a; 
namespace ConsoleApplication1 
{ 
    public class a 
    { 
     public string ff { get; set; } 
    } 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      other s = new other(); 
      a b = new a(); 
     } 
    } 
} 
namespace sssssss 
{ 

    public class a 
    { 
     public string ff { get; set; } 
    } 
} 

MSDN

76

我知道這是舊的,但有一個比列出的更容易。這適用於當您參考兩個程序集共享類型與確切相同的名稱和命名空間。

如果您在參考你的DLL右鍵單擊並選擇化子性質,你會看到這裏有一個所謂的「別名」

enter image description here

屬性的默認值是「全球性」。對於衝突的程序集之一將其更改爲任何其他值。在下面的例子中,我將它從「全局」更改爲「目標」。

接下來,在您的代碼文件中,您將不得不使用extern keyword將這個別名用作這些類型的根級別名稱空間。在這個例子中,你會發生在你的cs文件的頂部如下:

extern alias destination 

現在,這個文件中,你可以參考兩種類型。

extern alias destination; 
namespace Test 
{ 
    public static class TestClass 
    { 
     public static void Success() 
     { 
      var foo = destination::Some.Duplicate.Namespace.SomeDuplicateType(); 
      var bar = Some.Duplicate.Namespace.SomeDuplicateType(); 
     } 
    } 
} 
+0

欣賞更好的答案!這顯然是什麼別名基本上 – PandaWood 2013-08-09 04:05:28

+2

對我來說也絕對是最好的答案。 其他解決方案甚至不會工作,因爲我有兩個完全相同的dll,一個只是在另一個與ILMerge合併。已解決的問題 – Johnny 2015-09-05 19:04:59

+0

我想在這裏重新提問@bunkerdive的問題(最受歡迎的答案):您如何才能使用NuGet包來處理這個問題?如果您嘗試更改Alias VS會給您一個錯誤:無法修改源自導入文件的評估對象 – Geordie 2017-09-25 21:23:57

9

老問題,但發現了一個更容易的選擇... 選擇要使用... 在性能基準,改變別名爲「XYZ」 現在的代碼行,在頂部加入:

extern alias xyz; 

然後添加使用:

using xyz.VENDOR2.Type; 

或使用用另外的方式:

using OtherNameSpace = xyz.VENDOR2.Type; 

現在你應該可以明確地使用參考如下:

var abc = new xyz.VENDOR2.Type.abc(); 

var abc = new OtherNameSpace.abc(); 
+2

但是,如果它是被引用的NUGET包而不是常規的dll,這可以實現嗎? – bunkerdive 2016-09-28 23:42:14

+0

@bunkerdive它可能會以相同的方式使用或不使用NuGet包。當您安裝NuGet包時,包中的程序集引用應自動添加到Visual Studio項目中。在「解決方案資源管理器」視圖窗格中查看項目下的* References *節點。 – 2017-05-01 20:17:02

相關問題