当前位置:编程学习 > C#/ASP.NET >>

C#插件开发简单模型

一、前言

插件模型指应用程序由一些动态的独立模块构成,每个模块均具有一个或多个服务,并满足一定的插件协议,能够借助主程序实现主程序-插件,插件-插件之间的通讯。它定义了一套公共的接口,通过接口与插件进行通信,主要是通过反射来获取相关的属性和方法,然后再执行指定的操作。其实,它也可以理解为定义一套通用的解决方案,通过反射来获取相应的程序集的相关类型,然后执行这些指定类型的相关操作。它是一种即插即用的方案,更新及维护简便。

本文仅仅是描述插件开发的大体模型,设计比较简单,主要的步骤如下:

(1)、定义公共的接口以及抽象类。

(2)、定义和实现相关组件。

(3)、实现通用程序集反射操作类。

 

其中,公共的接口和抽象类定义在组件Jasen.Framework.Core中,该组件中提供通用程序集反射操作类AssemblyUtility;具体实现的相关组件为Jasen.Framework.Oracle、Jasen.Framework.Access和Jasen.Framework.SqlServer,它们都实现了Jasen.Framework.Core中的公共接口。客户端可以根据实际情况来进行相应的操作。相关组件图如下:

\

 

 

二、公共接口和抽象类的定义以及相关组件的定义和实现

首先,定义公共的接口以及抽象类,如下类图所示,定义一个公共的接口IDataTable,定义一个抽象类DataTable,这些公共的类型放置在最顶端的程序集中。而其他组件将分别重新创建,实现相对应的功能,如SqlServerDataTable、OracleDataTable和AccessDataTable实现各自的功能。注意:Assembly.LoadFile(file)动态加载程序集时,该程序集在当前的运行环境中必须不存在的,否则可能会出现意想不到的数据异常,因此相关组件的实现必须是独立的(仅仅是实现公共的接口)。

\

 

三、通用程序集反射操作类的实现

下面的AssemblyUtility主要是对程序集操作的通用类,可以根据指定目录以及文件列表动态获取相应的程序集。同时,也可以通过目录,文件以及程序集获取相关的类型集合和对象集合。其中需要注意的是,实现的子类必须提供默认构造函数。客户端可以通过该类获取相应的类型和对象集合,然后再执行相应的操作。这些操作都是通过动态加载程序集来实现的,代码如下所示:

    public static class AssemblyUtility
    {
        public static IEnumerable<Type> GetImplementdTypesByDirectory<T>(string baseDirectory)
        {
           IList<Assembly> assemblies= GetAssemblies(baseDirectory);
           List<Type> types = new List<Type>();
           foreach (Assembly assembly in assemblies)
           {
               types.AddRange(GetImplementdTypes<T>(assembly));
           }

           return types;
        }

        public static IEnumerable<Type> GetImplementdTypes<T>(string assemblyFile)
        {
            if (!File.Exists(assemblyFile))
            {
                return null;
            }
            try
            {
                return GetImplementdTypes<T>(Assembly.LoadFile(assemblyFile));
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static IEnumerable<Type> GetImplementdTypes<T>(Assembly assembly)
        {
            if (assembly == null)
            {
                return null;
            }

            return assembly.GetExportedTypes().Where(p =>
               p.IsSubclassOf(typeof(T)) && (!p.IsAbstract) && (!p.IsInterface));
        }

        public static IList<T> GetImplementedObjectsByDirectory<T>(string baseDirectory)
        {
            IList<Assembly> assemblies = GetAssemblies(baseDirectory);
            List<T> entities = new List<T>();
            foreach (Assembly assembly in assemblies)
            {
                entities.AddRange(GetImplementedObjects<T>(assembly));
            }

            return entities;
        }

        public static IList<T> GetImplementedObjects<T>(string assemblyFile)
        {
            if (!File.Exists(assemblyFile))
            {
                return null;             
            }
      &

补充:软件开发 , C# ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,