0

내가 요구 사항의 see MSDN link등록 무료 COM Interop를 초기화 - 매개 변수가없는 생성자

하나는 등록 무료 COM Interop를 라이브러리를 작성해야, 난에 대한 .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'를 만들 수 있습니까? 그런 다음 해당 객체를 사용하여 Test 클래스의 매개 변수화 된 생성자를 호출 할 수 있습니다. 여전히 요구 사항을 충족하는지 확실하지 않습니다. 나는 비슷한 일을했지만 항상 내 어셈블리를 등록했습니다. – pinkfloydx33

답변

2

당신은 그렇게 많이 그리워하지 않습니다. COM은 universal object factory을 사용하며 범용이기 때문에 인수를 사용할 수 없습니다. 그래서 기본 생성자로 C# 클래스를 만들어야하며 생성자 인수를 전달할 방법이 없습니다.

이 솔루션은 매우 간단합니다. 필요한 모든 것이 자신의 개체 팩토리이며 클라이언트 코드에 노출됩니다. 팩토리 함수는 C# 객체를 만드는 데 필요한 인수를 취할 수 있습니다. 또한 [ComVisible] 특성을 생략함으로써 간단하게 수행되는 팩토리 사용을 주장하기 때문에 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

게으른 <T>은 당신의 친구 인 Initialize()와 똑같은 개념이지만 깨끗한 구문과 쓰레드 안전합니다.