0

我需要編寫一個免費註冊COM互操作庫see MSDN link免費註冊COM互操作初始化 - 參數的構造函數

的要求之一是,我引用

「對於一個基於.NET的類與COM無註冊表激活兼容,該類必須具有默認構造函數,並且必須是公共的。「

當我讀它,我需要創建以下...(這在技術上的作品,和我沒有問題,通過COM實例化這一點)

[ComVisible(true)] 
[Guid("...")] 
public interface ITest 
{ 
    X(); 
    Y(); 
} 

[ComVisible(true)] 
[Guid("...")] 
[ClassInterface(ClassInterfaceType.AutoDispatch)] 
public class Test : ITest 
{ 
    private string x; 

    public Test() // default constructor 
    { 
    } 

    X() 
    { 
     // do something with "x" BUT "x" MUST be initialized before this method is called 
    } 

    Y() 
    { 
     // do something else with "x" BUT "x" MUST be initialized before this method is called 
    } 
} 

我正在尋找最好的方式爲了確保這個類在任何方法被調用之前(通過接口)被初始化,所以,除了構造函數,什麼是我下一個最好的初始化「x」的選項?至於我可以告訴用參數重載構造函數不是一個選項 - 通常我會用帶參數的構造函數初始化這個類,但是使用Registration Free COM,我沒有這個選項(或者我? )。

我覺得我的選擇是「初始化」功能,如...

public interface ITest 
{ 
    Initialize(string x); 
    X(); 
    Y(); 
} 

public class Test : ITest 
{ 
    private string x; 
    private bool Initialized; 

    public Test() // default constructor 
    { 
     Initialized = false; 
    } 

    Initialize(string x) 
    { 
     this.x = x; 
     Initialized = true; 
    } 

    X() 
    { 
     if (Initialized) 
     { 
      // do something with x 
     } 
     else 
     { 
      throw... 
     } 
    } 

    Y() 
    { 
     if (Initialized) 
     { 
      // do something else with x 
     } 
     else 
     { 
      throw... 
     } 
    } 
} 

我覺得這是混亂的,但可行的......但什麼更好的選擇,我缺少什麼?

+0

你可以使用一個接受參數的'Create'方法創建第二個類/接口「ITestFactory」嗎?然後可以使用該對象來調用Test類的參數化構造函數。我不確定這是否仍然符合要求。我做了類似的事情,但總是註冊我的程序集。 – pinkfloydx33

回答

2

你不會錯過那麼多。 COM使用universal object factory,因爲它是通用的,它不能接受任何參數。這就是爲什麼你必須創建一個帶默認構造函數的C#類,沒有任何方法可以傳遞構造函數參數。

該解決方案非常簡單,您需要的只是您自己的對象工廠並將其展示給客戶端代碼。工廠函數可以接受任何需要創建C#對象的參數。而且你讓你的Test類無法訪問客戶端代碼,因爲你想堅持使用工廠,只需通過省略[ComVisible]屬性來完成。這fleshes這一些示例聲明:

[ComVisible(true)] 
public interface ITestFactory { 
    ITest Create(string arg); 
} 

[ComVisible(true)] 
public class TestFactory { 
    public ITest Create(string arg) { 
     return new Test(arg); 
    } 
} 

[ComVisible(true)] 
public interface ITest { 
    // etc... 
} 

internal class Test { 
    private string needed; 
    public Test(string arg) { 
     needed = arg; 
    } 
    // ITest methods ... 
} 

這些類型的對象工廠中典型的例子可以在Office互操作被發現。 Excel不允許直接創建電子表格,例如,您必須使用Application.Workbooks.Add()。

+0

感謝您的回答。我最終使用了構建器模式,這是一個類似的答案。 – 0909EM

1

懶惰<T>是你的朋友,與Initialize()相同的想法,但語法更清晰,線程安全。