免注册 COM Interop Initialization - 无参数构造函数
Registration Free COM Interop Initialization - parameterless constructor
我需要编写一个注册免费 COM 互操作库 see MSDN link
其中一个要求是,我引用
"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."
当我阅读它时,我需要创建以下...(这在技术上是可行的,而且我通过 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
}
}
我正在寻找确保在调用任何方法(通过接口)之前初始化此 class 的最佳方法,因此,除了构造函数之外,我的下一个最佳选择是初始化 "x"?据我所知,用参数重载构造函数不是一个选项——通常我会用一个带参数的构造函数初始化这个 class,但是对于 Registration Free COM,我没有那个选项(或者我呢??)。
我认为我的替代方案是 "Initialize" 函数,例如...
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...
}
}
}
我觉得这很乱,但可行...但我还缺少什么更好的选择?
Lazy 是你的朋友,与你的 Initialize() 想法相同,但语法更清晰且线程安全。
你并没有错过那么多。 COM 使用 universal object factory 并且因为它是通用的,所以它不能接受任何参数。这就是为什么您必须使用默认构造函数创建 C# class,没有任何方法可以传递构造函数参数。
解决方案非常简单,您只需要拥有自己的对象工厂并将其公开给客户端代码即可。工厂函数可以采用创建 C# 对象所需的任何参数。你让客户端代码无法访问你的测试 class,因为你想坚持它使用工厂,只需省略 [ComVisible] 属性即可。一些示例声明充实了这一点:
[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()。
我需要编写一个注册免费 COM 互操作库 see MSDN link
其中一个要求是,我引用
"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."
当我阅读它时,我需要创建以下...(这在技术上是可行的,而且我通过 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
}
}
我正在寻找确保在调用任何方法(通过接口)之前初始化此 class 的最佳方法,因此,除了构造函数之外,我的下一个最佳选择是初始化 "x"?据我所知,用参数重载构造函数不是一个选项——通常我会用一个带参数的构造函数初始化这个 class,但是对于 Registration Free COM,我没有那个选项(或者我呢??)。
我认为我的替代方案是 "Initialize" 函数,例如...
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...
}
}
}
我觉得这很乱,但可行...但我还缺少什么更好的选择?
Lazy
你并没有错过那么多。 COM 使用 universal object factory 并且因为它是通用的,所以它不能接受任何参数。这就是为什么您必须使用默认构造函数创建 C# class,没有任何方法可以传递构造函数参数。
解决方案非常简单,您只需要拥有自己的对象工厂并将其公开给客户端代码即可。工厂函数可以采用创建 C# 对象所需的任何参数。你让客户端代码无法访问你的测试 class,因为你想坚持它使用工厂,只需省略 [ComVisible] 属性即可。一些示例声明充实了这一点:
[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()。