繁体   English   中英

免费注册COM Interop初始化-无参数构造函数

[英]Registration Free COM Interop Initialization - parameterless constructor

我需要编写一个免费注册的COM Interop库, 请参见MSDN链接

要求之一是,我引用

“要使基于.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...
        }
    }
}

我觉得这很麻烦,但是可行...但是我缺少什么更好的选择?

您并没有那么想念。 COM使用通用对象工厂,并且因为它是通用对象,所以不能接受任何参数。 这就是为什么必须使用默认构造函数创建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()。

Lazy <T>是您的朋友,与Initialize()的想法相同,但语法和线程安全也更简洁。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM