C# 反射研究入门实例-----插件接口研究

非科班出身对这些不常用到的知识很好奇,今天有空,研究下。

个人理解反射就是不直接通过namespace或者class 获取到想要的class然后操作它

形象点说就是,通常我们引用某程序集的方式有点像指腹为婚 ,你刚懂事你妈就告诉你,邻村的小凤将来是你的媳妇儿,你找她的方法就是骑着你的forever到她的村头 叫她的名字

优点:你不会光棍、你会很快生小孩、你很了解她、不了解就问你妈

缺点:你想起了楚门

映射呢,就可以理解为自由恋爱了,春天到了你需要一个女朋友 ,你有一些要求:女,长发,胸大,你找她的方式就是爬到山顶,眯着眼睛,你略带拘谨的目光扫过附近的所有村庄,你有可能一下子无法找到她,也可能找不到

优点:自由恋爱

缺点:你要花很多时间去寻找、有可能找不到、你对姑娘不是特别了解

 

在网上看到一个比较实际的例子,就是播放器支持的格式,你开发了一个播放器,目前只支持MP4,你没有更多精力去开发其他格式的支持,但是你留了一个插件接口给别人,别人就可以开发插件来支持其他格式,知道用处才有方向。

写播放器当然超出我的能力了。。

我假设了一个类似的场景:

字符串加密,比如你开发了一个日记累的应用,你主动把用户日记加密存储,但是小陈对你的加密方式并不放心,他希望他可以自定义一套加密方式,在保存的时候用

构想:

1.用户上传dll ,在他保存的时候调用他的dll

2.为了保证无论用户什么加密都可以得到加密结果字符串,需要限定加密方法名、参数、返回值,就是做一个接口

interface 加密接口{

          string GetEncodeString(string str);

}

3.用户下载这个接口dll,引用并继承

public class 客户a的加密类:加密接口

{

     public 客户a的加密类(){}

     public string GetEncodeString(string str){

            /****加密str****/

            return str;

    }

}

4.后台处理、调用客户加密

System.Reflection.Assembly ass = Assembly.LoadFrom(dll保存路径); //加载DLL
System.Type t = ass.GetType("客户a的加密类");//获得类型
object o = System.Activator.CreateInstance(t);//创建实例
System.Reflection.MethodInfo mi = t.GetMethod("GetEncodeString");//获得方法
mi.Invoke(o, new object[] { ****});//调用方法

实现:

以上是大体思路以及一些伪代码,有一点不太靠谱的是用户直接上传通过路径调用,在我最开始的想法是第三方根据接口开发dll,我作为开发者加载此dll,至于如何调用就成了一个尴尬的问题了,我的设计是客户提交信息时告诉我要调用的dll,然后通过反射查找所有实现interface的Assembly(程序集),然后查找到指定的class,为了定位到type同时不限制class的名字,限制接口增加了一个codeType属性,通过属性确定type,代码如下:

接口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StringOpertor
{
    public interface IStringEncode
    {
        /// <summary>
        /// 扩展类必须声明其类名(供映射获取)
        /// </summary>
        string codeType { get; }
        /// <summary>
        /// 扩展类必须实现本接口的功能函数
        /// </summary>
        /// <returns></returns>
        string StringEncode(string formerStr);
    }
}

客户的实现

using System.Security.Cryptography; 
namespace StringOpertor
{
    /// <summary>
    /// 字符串加工类
    /// </summary>
    public class StringMaker:IStringEncode
    { 
        public StringMaker()
        {

        }
        //

        //接口属性
        private string _codeType="MD5";
        public string codeType
        {
            get{
                return _codeType;
            } 
        }

        /// <summary>
        /// 接口函数:字符串加密MD
        /// </summary>
        /// <param name="formerStr">原字符串</param>
        /// <returns>加工后的字符串</returns>
        public string StringEncode(string formerStr) {  
            //字符串处理
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] bytValue, bytHash;
            bytValue = System.Text.Encoding.UTF8.GetBytes(formerStr);
            bytHash = md5.ComputeHash(bytValue);
            md5.Clear();
            string sTemp = "";
            for (int i = 0; i < bytHash.Length; i++)
            {
                sTemp += bytHash[i].ToString("X").PadLeft(2, '0');
            }
            return sTemp.ToLower(); 
        }
    }
}

 

调用

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Web;

namespace 反射研究
{
    class StringEncoder
    {
        public StringEncoder() { }
        public string GetEncodeString(string codeType, string formerStr)
        {
            HttpContext c = HttpContext.Current;
            string returnValue = null;

            //获取类型信息(依据接口参数) 
            System.AppDomain _Domain = System.AppDomain.CurrentDomain;
            Assembly[] _AssemblyList = _Domain.GetAssemblies();
            for (int i = 0; i != _AssemblyList.Length; i++)
            {
                //获取程序集
                Assembly ass = _AssemblyList[i];
                //获取程序集的所有类
                Type[] types = ass.GetTypes();
                for (int j = 0; j != types.Length; j++)
                {
                    Type type = types[j];
                    //根据是否实现接口IStringEncode筛选
                    if (type.GetInterface("StringOpertor.IStringEncode") != null)
                    { 
                        PropertyInfo p = type.GetProperty("codeType"); 
                        if (p == null || !p.CanRead)
                            continue;
                        try
                        {
                            //构造器的参数
                            object[] constuctParms = new object[] { codeType };
                            //根据类型创建对象
                            object dObj = Activator.CreateInstance(type, null);

                            object className = p.GetValue(dObj, null);
                            if (codeType == className.ToString())
                            {
                                //获取方法的信息
                                MethodInfo method = type.GetMethod("StringEncode");
                                //调用方法的一些标志位,这里的含义是Public并且是实例方法,这也是默认的值
                                BindingFlags flag = BindingFlags.Public | BindingFlags.Instance;
                                //GetValue方法的参数
                                object[] parameters = new object[] { formerStr };
                                //调用方法,用一个object接收返回值
                                returnValue = method.Invoke(dObj, flag, Type.DefaultBinder, parameters, null).ToString();

                                return returnValue;

                            }
                        }
                        catch (Exception ex)
                        {
                        }
                    }

                }
            }
            return null;
        }
    }
}

显示

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="反射研究.Index" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        加密类型:<asp:TextBox ID="d_codeType" runat="server"></asp:TextBox>
         加密字符串:<asp:TextBox ID="d_formerStr" runat="server"></asp:TextBox>
        <asp:Button ID="Button1" runat="server" Text="加密" OnClick="Button1_Click" />
        结果:<asp:Label ID="d_result" runat="server" Text="Label"></asp:Label>
    </div>
    </form>
</body>
</html>

 

using System; 
namespace 反射研究
{
    public partial class Index : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            string codeType = d_codeType.Text;
            string formerStr = d_formerStr.Text;
            StringEncoder se = new StringEncoder();
            string result = se.GetEncodeString(codeType, formerStr);
            d_result.Text = result;
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值