0

私はsee MSDN link登録無料COM相互運用機能の初期化 - パラメータなしのコンストラクタ

登録無料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"を初期化する次のベスト・オプションは何ですか?限り、私はパラメータを使用してコンストラクタのオーバーロードを伝えることができるオプションではありません - 通常、私はパラメータを取ったコンストラクタでこのクラスを初期化しますが、登録無料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'という2番目のクラス/インタフェースを作ることができますか?そのオブジェクトを使用して、Testクラスのパラメーター化されたコンストラクターを呼び出すことができます。まだ要件を満たしているかどうかはわかりません。私は似たようなことをしましたが、私のアセンブリは常に登録していました。 – pinkfloydx33

答えて

2

あなたはあまりそれを逃していません。 COMはuniversal object factoryを使用し、普遍的なので引数を取ることはできません。つまり、デフォルトのコンストラクタを使用してC#クラスを作成する必要があります。コンストラクタ引数を渡す方法はありません。

解決方法は非常に簡単です。必要なのは自分自身のオブジェクトファクトリであり、クライアントコードに公開するだけです。ファクトリ関数は、C#オブジェクトを作成するために必要な引数を取ることができます。また、[ComVisible]属性を省略するだけで、Factoryクラスを使用することを主張したいので、Testクラスはクライアントコードにアクセスできなくなります。

[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 interopにあります。 Excelでは、スプレッドシートを直接作成することはできません。たとえば、Application.Workbooks.Add()を使用する必要があります。

+0

あなたの答えをありがとう。私は同様の答えであるビルダーパターンを使用して終了しました。 – 0909EM

1

Lazy <T>は、あなたのInitialize()と同じアイデアですが、より洗練された構文とスレッドセーフです。

関連する問題