Динамическое создание типа интерфейса
От: PeterPan Россия  
Дата: 13.08.10 13:59
Оценка:
Задача создать интерфейс в run-time.
Почему после объявления медода интерфейса, я не могу до него "добраться".
см. код ниже
            string outputdir = "c:\\";
            string fname = "Hello.World.dll";

            // Define the assembly name 
            AssemblyName bAssemblyName = new AssemblyName();
            bAssemblyName.Name = "Hello.World";
            bAssemblyName.Version = new System.Version(1, 2, 3, 4);

            // Define the new assembly and module 
            AssemblyBuilder bAssembly =
               System.AppDomain.CurrentDomain.DefineDynamicAssembly(bAssemblyName, 
                   AssemblyBuilderAccess.Save, outputdir);
            ModuleBuilder bModule = bAssembly.DefineDynamicModule(fname, true);

            TypeBuilder tInterface = bModule.DefineType("IFoo", 
               TypeAttributes .Abstract| TypeAttributes.Interface | TypeAttributes.Public);

            MethodBuilder methodBuilder = tInterface.DefineMethod("HelloWorld",
                MethodAttributes.Abstract | MethodAttributes.Virtual,
                typeof(void),
                Type.EmptyTypes);

            Type tInt = tInterface.CreateType();

            if(tInt.GetMethods() == null)
                throw new Exception("Я же объявил метод, где он?");


Превосхищая вопрос "зачем?" напишу:
Для того чтобы позже при реалиации интерфейса перегрузить этот метод


    typeBuilder = modBuilder.DefineType(typeName,
             TypeAttributes.Public |TypeAttributes.Class,
             null, tInt);

    methodBuilder = typeBuilder.DefineMethod("HelloWorld",
        MethodAttributes.Public | MethodAttributes.Virtual,
        typeof(void),
        Type.EmptyTypes);
           
     MethodInfo helloWorldMehodInfo =
          tInt.GetMethod("HelloWorld");
     typeBuilder.DefineMethodOverride(methodBuilder, tInt);
Re: Динамическое создание типа интерфейса
От: TK Лес кывт.рф
Дата: 13.08.10 20:23
Оценка:
Здравствуйте, PeterPan, Вы писали:

PP>Задача создать интерфейс в run-time.


Это http://stackoverflow.com/questions/1822047/how-to-emit-explicit-interface-implementation-using-reflection-emit смотрели?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: Динамическое создание типа интерфейса
От: Jolly Roger  
Дата: 14.08.10 05:45
Оценка:
Здравствуйте, PeterPan, Вы писали:

А можно озвучить решаемую задачу более подробно? Обрабатывать неизвестно какие события с неизвестно какой сигнатурой от неизвестно каких серверов — задача понятная для разного рода wizard'ов, создающих врапперы, но с этим вроде как должны справиться TypeLibConverter или AxImporter . А обычное приложение какую пользу может из этого извлечь?

В принципе, если серверы генерят события через dispinterface, то достаточно просто их принять одним объектом, реализующем IDispatch. Нужно просто в QueryInterface на запрос диспинтерфейсов отдавать IDispatch, и все события пойдут в IDispatch.Invoke. В нативном коде это делается элеменарно, такую реализацию часто используют в качестве базового класса приёмников событий. Вероятно, можно попробовать провернуть это и в NET.
"Нормальные герои всегда идут в обход!"
Re[2]: Динамическое создание типа интерфейса
От: PeterPan Россия  
Дата: 15.08.10 06:15
Оценка:
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, PeterPan, Вы писали:


PP>>Задача создать интерфейс в run-time.


TK>Это http://stackoverflow.com/questions/1822047/how-to-emit-explicit-interface-implementation-using-reflection-emit смотрели?


Да спасибо, уже сделал. У меня был MethodAttributes.Public атрибут пропущен.
Re[2]: Динамическое создание типа интерфейса
От: PeterPan Россия  
Дата: 15.08.10 06:29
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, PeterPan, Вы писали:


JR>А можно озвучить решаемую задачу более подробно? Обрабатывать неизвестно какие события с неизвестно какой сигнатурой от неизвестно каких серверов — задача понятная для разного рода wizard'ов, создающих врапперы, но с этим вроде как должны справиться TypeLibConverter или AxImporter . А обычное приложение какую пользу может из этого извлечь?


Если имеется в виду задача из этой
Автор: Jolly Roger
Дата: 14.08.10
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал.
Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.


JR>В принципе, если серверы генерят события через dispinterface, то достаточно просто их принять одним объектом, реализующем IDispatch. Нужно просто в QueryInterface на запрос диспинтерфейсов отдавать IDispatch, и все события пойдут в IDispatch.Invoke. В нативном коде это делается элеменарно, такую реализацию часто используют в качестве базового класса приёмников событий. Вероятно, можно попробовать провернуть это и в NET.
Re[3]: Динамическое создание типа интерфейса
От: Jolly Roger  
Дата: 15.08.10 13:06
Оценка:
Здравствуйте, PeterPan, Вы писали:

PP>Если имеется в виду задача из этой
Автор: Jolly Roger
Дата: 14.08.10
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал.

PP>Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.

Из той темы конечная цель так-же не ясна, как и из этой. Если сигнатуры заранее известны, то скорее всего пляски с рантайм генерацией типов вообще не нужны. Впрочем, дело Ваше.
"Нормальные герои всегда идут в обход!"
Re[4]: Динамическое создание типа интерфейса
От: PeterPan Россия  
Дата: 15.08.10 15:58
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, PeterPan, Вы писали:


PP>>Если имеется в виду задача из этой
Автор: Jolly Roger
Дата: 14.08.10
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал.

PP>>Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.

JR>Из той темы конечная цель так-же не ясна, как и из этой. Если сигнатуры заранее известны, то скорее всего пляски с рантайм генерацией типов вообще не нужны. Впрочем, дело Ваше.


Постараюсь описать задачу подробнее
На старте известны: ProgID COM объекта и сигнатура событий (название, тип возвращаемого значения, названия аргументов и их типы) этого объекта, пусть, например, это будет void OnError(string msg).
Цель — подписаться на событие этого COM-объекта в среде .Net Framework, в нашем случае — иметь возможность журналировать msg.
К сожалению я не нашел способа делать это без рантайм генерации типов. Если есть такая возможность, буду признателен за пример.
Re[5]: Динамическое создание типа интерфейса
От: PeterPan Россия  
Дата: 15.08.10 16:02
Оценка:
Здравствуйте, PeterPan, Вы писали:

PP>Здравствуйте, Jolly Roger, Вы писали:


JR>>Здравствуйте, PeterPan, Вы писали:


PP>>>Если имеется в виду задача из этой
Автор: Jolly Roger
Дата: 14.08.10
темы, то сигнатура событий известна. Как получить мета описания типов, методов аргументов я там описал.

PP>>>Как принимать события я там также описал. Мне остается закончить динамическую генерацию интерфейса и объекта приемника событий и "подсунуть" его в СОМ-объекты — генератор событий.

JR>>Из той темы конечная цель так-же не ясна, как и из этой. Если сигнатуры заранее известны, то скорее всего пляски с рантайм генерацией типов вообще не нужны. Впрочем, дело Ваше.


Я видимо неверно указал сылку на предыдущую тему
Автор: PeterPan
Дата: 05.08.10
Re[5]: Динамическое создание типа интерфейса
От: Jolly Roger  
Дата: 15.08.10 17:18
Оценка:
Здравствуйте, PeterPan, Вы писали:

PP>На старте известны: ProgID COM объекта и сигнатура событий (название, тип возвращаемого значения, названия аргументов и их типы) этого объекта, пусть, например, это будет void OnError(string msg).

PP>Цель — подписаться на событие этого COM-объекта в среде .Net Framework, в нашем случае — иметь возможность журналировать msg.

Для описанного случая — здесь
Автор: grigorash
Дата: 10.07.08
. Там не совсем такая ситуация, но предложенное решение — то, что нужно Вам, и оно работает, я проверил. Если всё-же есть ещё какие-то нюансы, не указанные Вами — вот ссылка 2
Автор: Greeter
Дата: 16.01.06
, но это я пока не проверял.

Но прежде проверьте, вполне возможно, что Вам будет достаточно объявить класс без явных интерфейсов, с публичным методом OnError(string msg) и аттрибутом ClassInterface(ClassInterfaceType.AutoDispatch)
"Нормальные герои всегда идут в обход!"
Re[6]: Динамическое создание типа интерфейса
От: PeterPan Россия  
Дата: 16.08.10 03:19
Оценка:
Здравствуйте, Jolly Roger, Вы писали:

JR>Здравствуйте, PeterPan, Вы писали:


PP>>На старте известны: ProgID COM объекта и сигнатура событий (название, тип возвращаемого значения, названия аргументов и их типы) этого объекта, пусть, например, это будет void OnError(string msg).

PP>>Цель — подписаться на событие этого COM-объекта в среде .Net Framework, в нашем случае — иметь возможность журналировать msg.

JR>Для описанного случая — здесь
Автор: grigorash
Дата: 10.07.08
. Там не совсем такая ситуация, но предложенное решение — то, что нужно Вам, и оно работает, я проверил. Если всё-же есть ещё какие-то нюансы, не указанные Вами — вот ссылка 2
Автор: Greeter
Дата: 16.01.06
, но это я пока не проверял.


JR>Но прежде проверьте, вполне возможно, что Вам будет достаточно объявить класс без явных интерфейсов, с публичным методом OnError(string msg) и аттрибутом ClassInterface(ClassInterfaceType.AutoDispatch)


Не вижу по ссылкам то, что мне надо, а именно подписку на события.

Давайте по порядку:

1.Я создаю COM -объект по progID

      Type tp = Type.GetTypeFromProgID(progID);
      object comObject = Activator.CreateInstance(tp);


2. А дальше
Re[7]: Динамическое создание типа интерфейса
От: Jolly Roger  
Дата: 16.08.10 11:46
Оценка:
Здравствуйте, PeterPan, Вы писали:

PP>Не вижу по ссылкам то, что мне надо, а именно подписку на события.


Хм, а причём тут подписка? Подписка ровно так-же, как Вы собирались с ручной генерации типов

var cpc = comObject as IConnectionPointContainer;
IConnectionPoint cp;
cpc.FindConnectionPoint(ref EventsIId, out cp);
var sink = new MyEventSink();
cp.Advise(sink, out cookie);


Только вместо сгенерированного MyEventSink пердать в Advise можно попробовать TransparentProxy из примера.
"Нормальные герои всегда идут в обход!"
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.