Принципы объектно-ориентированного программирования

         

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



Позднее связывание с компонентами 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); > } }

 

Содержание раздела