Поиск

Позднее связывание с компонентами COM

Оба приложения — AirlineClientlApp и AirlineClient2App — используют метаданные RCW для раннего связывания .NET-клиента с объектом СОМ. Хотя раннее связывание обеспечивает строгую проверку типов в период компиляции, возможность вывода подсказок о типах в средах разработки (например, Visual Studio.NET) и, конечно, лучшую производительность, могут быть случаи, когда у вас нет метаданных периода компиляции для объекта СОМ, с которым вы осуществляете связывание. И тогда вам требуется позднее (динамическое) связывание (late binding) с этим компонентом. Например, если компонент, который вы пытаетесь задействовать, содержит только диспинтерфейс, то при использовании этого компонента вы во многом ограничены поздним связыванием.

Вы можете производить позднее связывание с СОМ-объектом через механизм отражения (см. главу 16). Для этого вам нужно знать ProgID компонента, так как статический метод Create Instance класса System.Acti-vator требует объект Type. ProgID компонента позволяет вызвать метод GetTypeFromProgID класса System. Type. Он вернет допустимый объект Туре .NET, который вы в дальнейшем сможете использовать при вызове метода System.Activator.Createlnstance. Сделав это с помощью метода экземпляра System. Type.InvokeMember объекта Туре, полученного от метода GetTypeFromProgID, вы сможете вызывать любые методы или свойства, которые поддерживает интерфейс по умолчанию компонента.

Все что вам нужно знать, — это имя метода или свойства и сведения о параметрах, принимаемые при вызове метода. При вызове метода поздно связанного компонента вы можете передать параметры, объединив их в универсальный массив System.Object, после чего последний передается методу. Вам также потребуется установить флаги связывания (binding flags) в зависимости от того, что вы делаете: вызываете метод или получаете/устанавливаете значение свойства.

Как видно из следующего кода, здесь придется поработать чуть больше, чем при раннем связывании. Однако вы будете очень рады и этому, если позднее связывание — единственный выбор.

using System;
using System.Runtime.InteropServices;
using System.Reflection;
using AIRLINEINFORMATIONLib;
public class AirlineClientSApp {
public static void Main() {
///////////////////////////////////////////////
/// ПОЗДНЕЕ СВЯЗЫВАНИЕ
///////////////////////////////////////////////
try
{
object objAirlineLateBound; Type objTypeAirline;
object[] array!nputParams= { "Air Scooby 1C 5678" };
objTypeAirline = Type.GetTypeFromProgID
("Airlinelnformation.Airlinelnfo");
ObjAirlineLateBound = Activator.Createlnstance
(objTypeAirline);
String str = (String)objTypeAirline.InvokeMember
("GetAirlineTiming", BindingFlags.Default | BindingFlags.
InvokeMethod, null, objAirlineLateBound, arraylnputParams);
Console.WriteLine("{0}", str);
String strTime = (String)objTypeAirline.InvokeMember
("LocalTimeAtOrlando", BindingFlags.Default |
BindingFlags.GetProperty, null, objAirlineLateBound, new object [] {});
Console.WriteLine ("Hi there !. The Local Time in " +
"Orlando,Florida is: {0}", strTime); }
catch(COMException e) {
Console.Writel_ine("0ops- We encountered an error " +
"for Airline {0}. The Error message " + "is : {1}.
The Error code is {2}", strFoodJunkieAirline,
e.Message,e.ErrorCode); > } }