Регистрация Бесплатная COM Interop Initialization - конструктор без параметров
Мне нужно написать бесплатную библиотеку 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"? Насколько я могу сказать, перегрузка конструктора с параметром не является опцией - Обычно я инициализирую этот класс конструктором, который принимает параметры, однако в случае регистрации 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...
}
}
}
Я чувствую, что это грязно, но выполнимо... но какой лучший вариант мне не хватает?
2 ответа
Вы не так сильно скучаете. COM использует универсальную фабрику объектов и, поскольку она универсальна, она не может принимать никаких аргументов. Вот почему вы должны создать класс C# с конструктором по умолчанию, нет способа передать аргументы конструктора.
Решение довольно простое, все, что вам нужно, это ваша собственная фабрика объектов и предоставить ее клиентскому коду. Функция factory может принимать любые аргументы, необходимые для создания вашего объекта C#. И вы делаете ваш класс Test недоступным для клиентского кода, поскольку вы хотите настаивать на том, чтобы он использовал фабрику, просто сделав это, пропустив атрибут [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 Interop. Excel не позволяет вам создавать электронную таблицу напрямую, например, вы должны использовать Application.Workbooks.Add().
Lazy