zoukankan      html  css  js  c++  java
  • C#实现插件式开发的一个Demo分享

    winform程序,很多时候都需要用到插件式的,所以本人做了一个Demo,思路跟网上思路基本一致,现在共享出来如有需要的朋友可以下载。

    申明:部分代码来源于网上,当然思路也是,呵呵

    原理很简单:

    一:定义插件接口

    二:实现插件接口并建立不同工项目,使其在生成时生成不同的DLL

    三:主程序运行时根据接口名利用反射对插件目录的DLL进行加载,加载完成后便可以使用插件接口定义的方法或属性了。

    下面上几张图,有兴趣的朋友可以先看看,觉得值得一看的朋友可以下载。

    项目结构:

    DefaultPlugin,PosPlugin两个项目均为插件,均实现了Iplugin接可

    Iplugin接口
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using System.Windows.Forms;

    namespace WinDemo.Core
    {
        
    public interface Iplugin
        {

            PluginInfoAttribute PluginInfo
            { 
    getset; }
            
    bool IsLoad
            {
                
    get;
                
    set;
            }

            Image ModulePicture
            {
                
    get;
            }

            Image ModulePictureEnter
            {
                
    get;
            }

            Image ModulePictureClick
            {
                
    get;
            }

            
    string ModuleName
            {
                
    get;
            }


            Dictionary
    <string, EventHandler> ChildNodes
            {
                
    get;
            }

            ILoadForm FormLoader
            {
                
    get;
                
    set;
            }

           
        }
    }

     

    用于加载插件的类 PluginLoader
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Reflection;
    using System.IO;
    using System.Windows.Forms;
    using System.Collections;

    namespace WinDemo.Core
    {
        
    public static class PluginLoader
        {

            
    public static List<Iplugin> plugins = new List<Iplugin>();
            
    private static ArrayList piProperties = new ArrayList();
            
            
    private static bool IsValidPlugin(Type t)
            {
                
    bool ret = false;
                Type[] interfaces 
    = t.GetInterfaces();
                
    foreach( Type theInterface in interfaces ) {
                    
    if (theInterface.FullName == "WinDemo.Core.Iplugin")
                    {
                        ret 
    = true;
                        
    break;
                    }
                }
                
    return ret;
            }


           

            
    public static void LoadAllPlugins()
            {
                
    string[] files = Directory.GetFiles(Application.StartupPath + "\\plugin\\");
                
    int i = 0;
                PluginInfoAttribute typeAttribute 
    = new PluginInfoAttribute();
                
    foreach (string file in files)
                {
                    
    string ext = file.Substring(file.LastIndexOf("."));
                    
    if (ext != ".dll"continue;
                    
    try
                    {
                        Assembly tmp 
    = Assembly.LoadFile(file);
                        Type[] types 
    = tmp.GetTypes();
                        
    bool ok = false;
                        
    foreach (Type t in types)
                            
    if (IsValidPlugin(t))
                            {
                                Iplugin plugin 
    = (Iplugin)tmp.CreateInstance(t.FullName);
                                plugins.Add(plugin);
                                
    object[] attbs = t.GetCustomAttributes(typeAttribute.GetType(), false);
                                PluginInfoAttribute attribute 
    = null;
                                
    foreach (object attb in attbs)
                                {
                                    
    if (attb is PluginInfoAttribute)
                                    {
                                        attribute 
    = (PluginInfoAttribute)attb;
                                        attribute.Index 
    = i;
                                        i
    ++;
                                        ok 
    = true;
                                        
    break;
                                    }
                                }

                                
    if (attribute != null)
                                {
                                    piProperties.Add(attribute);
                                    plugin.PluginInfo 
    = attribute;
                                }
                                
    else throw new Exception("未定义插件属性");
                                
    if (ok) break;
                            }
                    }
                    
    catch (Exception err)
                    {
                        
    throw err;
                    }
                }
                plugins.Sort((p1, p2) 
    => {
                    
    return p2.PluginInfo.Index - p1.PluginInfo.Index;
                });
            }
        }
    }

      

    Iplugin的实现类PosPlugin类
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using WinDemo.Core;
    using System.Windows.Forms;
     

    namespace DefaultPlugin
    {
        [PluginInfo(
    "Default","1.0","XH","www.cnporter.com",true,2)]
        
    public class Default : WinDemo.Core.Iplugin
        {
            
    private Dictionary<string, EventHandler> _ChildNodes = new Dictionary<string, EventHandler>();
            
    private LeftNav frmLeftNav = new LeftNav(); 
            
    public static ILoadForm Formloader ;
            
    public Default()
            {

                _ChildNodes.Add(
    "菜单五", (sender,e) =>
                {
                    MessageBox.Show(sender.ToString());
                });
                _ChildNodes.Add(
    "菜单四", (sender, e) =>
                {
                    MessageBox.Show(sender.ToString());
                });
                _ChildNodes.Add(
    "菜单三", (sender, e) =>
                {
                    MessageBox.Show(sender.ToString());
                });
                _ChildNodes.Add(
    "菜单二", (sender, e) =>
                {
                    MessageBox.Show(sender.ToString());
                });
                _ChildNodes.Add(
    "菜单一", (sender, e) =>
                {
                    FormLoader.LoadNavFrm(frmLeftNav);
                });
            }

            

            
    public Image ModulePicture
            {
                
    get
                {
                    
    return ((System.Drawing.Image)(ImageResource.Index));
                }
            }

            
    public Image ModulePictureEnter
            {
                
    get
                {
                    
    return ((System.Drawing.Image)(ImageResource.IndexEnter));
                }
            }

            
    public Image ModulePictureClick
            {
                
    get
                {
                    
    return ((System.Drawing.Image)(ImageResource.IndexClick));
                }
            }

            
    public string ModuleName
            {
                
    get
                {
                    
    return "首页";
                }
            }

            
    public Dictionary<string, EventHandler> ChildNodes
            {
                
    get
                {
                    
    return _ChildNodes;
                }
            }




            
    public bool IsLoad
            {
                
    get;
                
    set;
            }
            
            
    public ILoadForm FormLoader
            {
                
    get
                {
                    
    return Formloader;
                }
                
    set
                {
                    Formloader 
    = value;
                }
            }



            
    public PluginInfoAttribute PluginInfo
            {
                
    get;
                
    set;
            }
        }

     
    }
     

    此图现在有两个插件

     

    运行效果如下

     

    源码下载

  • 相关阅读:
    centos8 将SSSD配置为使用LDAP并要求TLS身份验证
    Centos8 搭建 kafka2.8 .net5 简单使用kafka
    .net core 3.1 ActionFilter 拦截器 偶然 OnActionExecuting 中HttpContext.Session.Id 为空字符串 的问题
    Springboot根据不同环境加载对应的配置
    VMware Workstation12 安装 Centos8.3
    .net core json配置文件小结
    springboot mybatisplus createtime和updatetime自动填充
    .net core autofac依赖注入简洁版
    .Net Core 使用 redis 存储 session
    .Net Core 接入 RocketMQ
  • 原文地址:https://www.cnblogs.com/xianhong/p/1988191.html
Copyright © 2011-2022 走看看