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()相同的想法,但语法更清晰,线程安全。