"Обновление" интерфейсов - PullRequest
7 голосов
/ 20 августа 2009

Пару дней назад я видел, как CoClassAttribute используется так, как я раньше не представлял.


[ComImport, CoClass(typeof(Foo)), Guid("787C1303-AE31-47a2-8E89-07C7257B1C43")]
interface IFoo {
    void Bar();
}

class Foo : IFoo {
    public void Bar() {
        Console.WriteLine("Oh retado!");
    }
}

используется как:


class CoClassDemo {
    public static void Show() {
        var a = new IFoo();
        a.Bar();
    }
}

Это не должно было меня удивлять, поскольку COM Interop делает именно это с первых дней .NET Framework. Я просто не обращал так много внимания при копании кода COM-взаимодействия в .NET Reflector.


method public hidebysig static void Show() cil managed
{
    .maxstack 1
    .locals init (
        [0] class ConsoleApplication1.IFoo a)
    L_0000: nop 
    L_0001: newobj instance void ConsoleApplication1.Foo::.ctor()
    L_0006: stloc.0 
    L_0007: ldloc.0 
    L_0008: callvirt instance void ConsoleApplication1.IFoo::Bar()
    L_000d: nop 
    L_000e: ret 
}

Что случилось, так это то, что вне контекста COM Interop я сразу же предположил, что это будет использоваться как инъекция зависимости бедного человека от времени компиляции .

Все, что нужно сделать, это избавиться от обычного префикса «I» в имени интерфейса (как это делает COM Interop).

Тогда нужно будет изменить атрибут CoClass, чтобы поменять реализацию на другую, насмешливо и т. Д.

Два недостатка, которые я вижу заранее, - это необходимость перекомпиляции (что в значительной степени ограничивает сценарии тестирования временем разработки) и возможные проблемы, связанные с циклическими зависимостями, когда интерфейсы и реализации развертываются в разных сборках.

Кто-нибудь играл с этой техникой? Есть ли другие недостатки? Другое использование?

1 Ответ

10 голосов
/ 20 августа 2009

Я знаю, что в выходные получено как минимум два сообщения в блоге - мой и Айенде .

Для большинства кода это должно рассматриваться просто как любопытство. Я думаю, что было бы неправильно использовать это для внедрения зависимостей, когда установленные платформы IoC / DI могут сделать работу намного лучше и проще.

В частности, этот подход основан на аварийном люке § 17.5, специфическом для Microsoft расширении спецификации ... Вы хотите, чтобы ваш код работал на Mono? Я не пробовал, но нет конкретной причины , чтобы он компилировался в gmcs / dmcs.

У Джона был лучший пример использования его в конкретном коде - для преднамеренной насмешки над COM, но это было для игры с .NET 4.0 / dynamic. Снова; это не относится к большинству «обычных» кодов.

Так нет; не делай этого - это просто удовольствие.

...