简体   繁体   English

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

[英]Registration Free COM Interop Initialization - parameterless constructor

I need to write a Registration Free COM Interop library see MSDN link 我需要编写一个免费注册的COM Interop库, 请参见MSDN链接

One of the requirements is, and I quote 要求之一是,我引用

"For a .NET-based class to be compatible with registry-free activation from COM, the class must have a default constructor and must be public." “要使基于.NET的类与COM的免注册激活兼容,该类必须具有默认构造函数且必须是公共的。”

As I read it, I need to create the following... (this technically works, and I have no problem instantiating this via 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
    }
}

I'm looking for the best way to ensure that this class is initialized before any methods are called (via the interface), so, other than a constructor, whats my next best option to initialize "x"? 我正在寻找确保在调用任何方法之前(通过接口)初始化该类的最佳方法,因此,除了构造函数之外,初始化“ x”的下一个最佳选择是什么? As far as I can tell overloading the constructor with a parameter isn't an option - Usually I would initialize this class with a constructor that took parameters, however with Registration Free COM, I don't have that option (or do I??). 据我所知,使用参数重载构造函数不是一个选择-通常,我会使用带有参数的构造函数来初始化此类,但是对于免费注册COM,我没有该选项(或者我没有? )。

I think my alternative is an "Initialize" function, such as... 我认为我的替代方法是“初始化”功能,例如...

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...
        }
    }
}

I feel that this is messy, but doable... but what better option am I missing? 我觉得这很麻烦,但是可行...但是我缺少什么更好的选择?

You are not missing that much. 您并没有那么想念。 COM uses a universal object factory and, because it is universal, it can't take any arguments. COM使用通用对象工厂,并且因为它是通用对象,所以不能接受任何参数。 Which is why you must create a C# class with a default constructor, there isn't any way to pass constructor arguments. 这就是为什么必须使用默认构造函数创建C#类的原因,没有任何方法可以传递构造函数参数。

The solution is a pretty simple one, all that you need is your own object factory and expose it to the client code. 该解决方案非常简单,您所需要的只是您自己的对象工厂,并将其公开给客户端代码。 The factory function can take any arguments you need to create your C# object. 工厂函数可以接受创建C#对象所需的任何参数。 And you make your Test class inaccessible to the client code, since you want to insist it uses the factory, simply done by omitting the [ComVisible] attribute. 而且,由于要坚持使用工厂,因此只需省略[ComVisible]属性即可使客户代码无法访问Test类。 Some sample declarations that fleshes this out: 一些示例声明充实了这一点:

[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 ...
}

Good examples of these kind of object factories can be found in Office interop. 在Office interop中可以找到这类对象工厂的很好的例子。 Excel does not allow you to create a spreadsheet directly for example, you have to use Application.Workbooks.Add(). Excel不允许您直接创建电子表格,例如,必须使用Application.Workbooks.Add()。

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

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

相关问题 使用免注册com激活(基于COM Interop的)ActiveX控制 - Activate a (COM Interop based) ActiveX contol using registration free com 免注册的类COM互操作和线程 - Registration-free COM-like interop and threading 免费注册COM互操作。 组件B参考组件A? - Registration free COM interop. assembly B reference assembly A? 无参数构造函数中的初始化(实体框架) - Initialization in a Parameterless Constructor (Entity Framework) 应该避免在无参数构造函数中初始化吗? - Initialization in a parameterless constructor should be avoided? COM Interop注册 - COM Interop registration 免费注册COM互操作:由于并排配置不正确,因此应用程序无法启动 - Registration Free COM Interop: The application has failed to start because its side-by-side configuration is incorrect 免注册COM互操作:在终结器中停用激活上下文将引发SEHException - Registration-Free COM Interop: Deactivating activation context in finalizer throws SEHException 64位COM dll和C#/。Net应用程序之间的免注册互操作 - Registration-free Interop between a 64-bit COM dll and a C#/.Net application EXE免费注册COM错误 - Registration Free COM errors with EXE
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM