• Pluge模式?反射?后期绑定?


    我不知道有没有这个设计模式,在网上搜索过也没有找到多少,只找到两篇文章。
    Pluge模式的功能是后期绑定还是条件外置,希望有知道的朋友确定一下。
    举例:
    一.通过配置文件:条件外置与反射实例
    接口:
    namespace SamplePlugePattern.Interface
    {
        /// <summary>
        /// define a action interface
        /// </summary>
        public interface IAction
        {
            void Burn();
        }
    }

    实现:
    namespace Machine
    {
        public class MachineT50:IAction
        {
            public void Burn()
            {
                Console.WriteLine("MachineT50 is burning now.");
            }
        }
    }

    客户类:
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Configuration;
    using SamplePlugePattern.Interface;

    namespace WorkPlat
    {
        /// <summary>
        /// Pluge Pattern Sample
        /// </summary>
        /// <remarks>author PetterLiu http://wintersun.cnblogs.com </remarks>
        class Program
        {
            static void Main(string[] args)
            {
                string AssemblyName = ConfigurationManager.AppSettings["AssemblyName"];
                string TypeName = ConfigurationManager.AppSettings["TypeName"];
                IAction action = UsingActivator(AssemblyName, TypeName);
                action.Burn();
            }

            private static IAction UsingCurrentAppDomain(string assemblyname, string typename)
            {
                return AppDomain.CurrentDomain.CreateInstanceAndUnwrap(assemblyname, typename) as IAction;
            }

            private static IAction UsingActivator(string assemblyname, string typename)
            {
                Assembly assembly = Assembly.Load(assemblyname);
                Type type = assembly.GetType(typename);
                return Activator.CreateInstance(type) as IAction;
            }
        }
    }

    这里使用的是appSettings,实际中还可以用自定义配制节。
    <configuration>
      <appSettings>
        <add key="AssemblyName" value="Machine"/>
        <add key="TypeName" value="Machine.MachineT50"/>
      </appSettings>
    </configuration>

    总结:为了使用一个在编译期间未知的类,在编译时未知的类型实现一个接口,而该接口是编译器所知的。为此,我们不得不创建第三个程序集:
    第一个程序集:定义一个接口;
    第二个程序集:是要被反射的程序集(要引用第一个程序集,并且要实现第一个程序集中定义的接口);
    第三个程序集:使用反射的程序集(也要引用第一个程序集,这样可以使用第一个程序集的接口)。
    二.C#后期绑定方式来调用COM对象
    实际应用当中,可能有的时候需要用到后期绑定方式来调用COM对象。

    1、静态方法System.Type.GetTypeFromProgID 方法 (String),该方法可获取与指定程序标识符 (ProgID) 关联的类型,如果在加载 Type 时遇到错误,则返回空值。
    通过它可获取对代表COM对象类型的Type对象的引用。此方法是专为 COM 组件支持提供的。
    2、静态方法System.Activator.CreateInstance(),使用与指定参数匹配程度最高的构造函数创建指定类型的实例。
    这里使用Activator.CreateInstance()创建COM对象的一个实例。
    3、System.Type类的非静态方法InvokeMember()可以创建一个在编译期间未知的类的实例,只需要在调用的时候使用BindingFlags枚举量中的SetProperty值即可对com对象的公共属性进行操作。
    InvokeMember方法的5个参数如下:  
      1)要调用的成员的名称。String,它包含要调用的构造函数、方法、属性或字段成员的名称;空字符串 (""),表示调用默认成员;对于 IDispatch 成员,则为一个表示 DispID 的字符串,例如“[DispID=3]”。
      2)BindingFlag枚举的值,表明调用的是属性还是方法等。这个位屏蔽,由一个或多个指定搜索执行方式的 BindingFlags 组成。访问可以是 BindingFlags 之一,如 Public、NonPublic、Private、InvokeMethod 和 GetField 等。不需要指定查找类型。如果省略查找类型,则将应用 BindingFlags.Public |BindingFlags.Instance。
      3)一个 Binder 对象,该对象定义一组属性并启用绑定,而绑定可能涉及选择重载方法、强制参数类型和通过反射调用成员。通常使用默认Binder 对象,即传递一个null值;
      4)对Com对象本身的引用;
      5)包含传递给要调用的成员的参数的数组。即希望给Com方法发送的输入参数数组。

    以下是测试代码,调用Word的com组件,并设置它的可视属性。

               object comObject;
                System.Type comObjectName;
                //参数
                object[] args = new object[1];
                //要获取的类型的 ProgID。
                string progID = "Word.Application";

                //与指定 ProgID 关联的类型,即获取相应的Com对象
                comObjectName = System.Type.GetTypeFromProgID(progID);
                //创建Com的实例
                if (comObjectName != null)
                {
                    comObject = Activator.CreateInstance(comObjectName);
                    //设置需要设置的参数值
                    args[0] = true;
                    //设置可视属性,显示Word窗体
                    comObjectName.InvokeMember("Visible", BindingFlags.SetProperty, null, comObject, args);
                }
    以下是调用方法示例(关闭刚才创建的Word窗体)             args = new object[3];
                comObjectName.InvokeMember("Quit", BindingFlags.InvokeMethod, null, comObject, args);

  • 相关阅读:
    C++覆盖、重载、多态区别
    C++的模板与类属类
    虚函数表和虚基类表
    常用的设计模式
    计算机内存中的对齐和C++ 类的存储空间大小
    C++的多态
    前端框架你究竟选什么
    [zt]程序员的本质
    javascript
    Web开发人员应有的15本免费电子书
  • 原文地址:https://www.cnblogs.com/AngelLee2009/p/1595599.html
Copyright © 2020-2023  润新知