2011-03-25 69 views
3

我有一個通用的基礎包裝類來封裝夫婦COM組件,我們使用:互操作類作爲泛型類型參數時出現什麼問題?

public class WrapperBase<T> : IDisposable 
    where T : new() 
{ 
    private T comObject = default(T); 
    private ComponentParameters parameters = null; 

    protected WrapperBase() 
    { 
     comObject = new T(); 
     Initialize(); 
    } 

    public void SetParameters(ComponentParameters parameters) 
    { 
     // ... 
     this.parameters = parameters; 
    } 

    // ... 
} 

現在我有一個具體的包裝類從這個基類繼承:

public class UserWrapper : WrapperBase<CUserClass> 
{ 
    public UserWrapper() : base() { } 

    public void SomeUserWrapperMethod() 
    { 
     // ... 
    } 
} 

的使用的類型(CUserClass)是COM互操作類型。添加COM對象作爲項目的引用後,此類型可用。

現在,我使用這個類在其他組件(它引用了上述類型定義的組件):

using (var user = new UserWrapper()) 
{ 
    user.SomeUserWrapperMethod(); 
} 

上面的代碼編譯罰款,但如果我實際調用SetParameters方法(這是隻有在Wrapperbase類中定義):

using (var user = new UserWrapper()) 
{ 
    user.SetParameters(someParameters); 
} 

我得到了(雙)編譯錯誤:

  • error CS0012: The type 'ComponentsAssembly.CUserClass' is defined in an assembly that is not referenced. You must add a reference to assembly 'Interop.ComponentsAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=...'.
  • ComponentWrappers.dll: (Related file) error CS0310: 'ComponentsAssembly.CUserClass' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'Contact.Wrappers.WrapperBase'

我試着添加對組件的引用,但仍然收到相同的錯誤消息。

在我將WrapperBase更改爲泛型類型之前,它曾用於工作,但後來在所有具體包裝中存在大量相同的代碼,所以我重構了它,使WrapperBase在過程中成爲泛型。

public class UserWrapper : WrapperBase<CUserClass> 
{ 
    public UserWrapper() : base() { } 

    public UserWrapper(ComponentParameters parameters) : base() 
    { 
     SetParameters(parameters) 
    } 
} 

,然後使用它像這樣:

using (var user = new UserWrapper(someParameters)) 
{ 
    user.SomeUserWrapperMethod(); 
} 

我其實可以通過增加一個構造函數的具體類,這需要「ComponentParameters」作爲參數,並調用內部的SetParameters解決這個問題

但我寧願有兩個方法工作(使用構造函數和明確調用SetParameters)。

有人可以向我解釋這裏發生了什麼,因爲在過去的幾個小時裏,我一直在撞牆。

+0

因此,讓我直截了當地說,WrapperBase <>是在ComponentWrappers.dll程序集中定義的,但實際上是在某種類型的主程序正確嗎?您在主程序本身中添加了對interop的引用,而不是COmponentWrapper.dll? – 2011-03-25 16:15:04

+0

@詹姆斯:不完全。 WrapperBase <>和UserWrapper都在ComponentWrappers.dll中,COM互操作DLL只在ComponentWrappers.dll中引用。在主程序中,我只使用UserWrapper類(並引用了ComponentWrappers.dll)。但即使我在主程序中添加了對interop dll的引用,仍然會得到相同的編譯錯誤。 – fretje 2011-03-25 16:17:21

+0

您是否嘗試過將互操作程序集的引用添加到主程序中? – 2011-03-25 16:19:54

回答

3

試試這個:當您在ComponentWrappers.dll中添加COM引用時,它會爲它生成一個interop程序集,並將其放入該程序集的構建位置(bin/release whatever)。在main中,導航到該位置並添加一個.NET引用(不是COM引用)並導航到該構建位置並將interop作爲參考。

我認爲這可能是感到困惑,因爲你在這兩個地方增加一條,作爲COM和它產生在每一個互操作...

另一種選擇是完全防止COM神器外界有任何公開的知名度你的裝配。要做到這一點,你必須在課堂上內部隱藏它等。

+0

(讓我知道如果這沒有意義,我可以進一步闡述)。本質上在ComponentWrappers.dll - >添加COM參考,主要添加在ComponentWrappers.dll的構建位置創建的互操作參考... – 2011-03-25 16:27:42

+0

好的,謝謝!這實際上做了竅門(添加引用,瀏覽生成文件夾選擇實際的互操作DLL)。但我想知道是否沒有辦法來防止這種情況。另外,當我從調試文件夾中選擇interop dll時,這會不會給發佈版本帶來問題,或者反過來呢? – fretje 2011-03-25 16:34:43

+0

通常,當我看到完成時,我看到人們在一個程序集中完全隔離對COM類的引用,所以它不會流血,或者將互操作存儲在單獨的位置。您可以直接從命令行生成互操作,然後像對待其他任何第三方程序集一樣對待它。或者有一個構建步驟創建它,並將其放置在給定的構建位置,然後讓這兩個程序集直接引用interop。 – 2011-03-25 17:41:14

相關問題