C#实现动态灵活调用业务方法的机制

博客介绍了C#实现动态灵活调用业务方法的机制。在某些应用中,存在业务处理方法和输出不同、需动态处理业务、业务数量不确定等情况。通过建立ADll、BDll、CDll三个类库,利用.NET反射机制,主体程序testReadDll可调用Dll指定方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:http://www.cnblogs.com/windsails/archive/2004/09/07/40574.aspx

 

C#实现动态灵活调用业务方法的机制

问题的提出:
在某些应用中往往会遇到这样的情况,例如最近遇到一个应用大致需要做这样的事情:
1.有几个比较类似的业务,但是每个的处理方法和输出不同;
2.需要动态的处理这些业务,例如某个时间可能需要处理甲业务,某个时间需要处理乙业务;
3.需要处理的业务数量不确定,随时可能有增减情况;
4.希望主体程序比较固定;



问题的分析:
我的想法是将这些业务规范为一些类库,固定好规范的接口。然后将这些Dll统一放在某个目录下面,目录中的Dll可以采取简单的XCopy方式来增删,并且需要保证主体程序不会长时间占用某个Dll资源,调用完就释放。


解决方法实验:
先将主要技术关键点抽取出来,关键就是建立一个可以动态调用某个目录下面的Dll中的某个方法的机制,因此先做一些简单的测试,将这个机制的建立弄清晰。

下面是这个简单的机制:
先建立了三个简单的类库,ADll,BDll,CDll。主体调用程序是testReadDll,它需要调用相对目录Dlls下面的全部Dll中的makeStr,没有输出错误信息继续执行下一个Dll。其中ADll和BDll都有类似的接口(这里并没有将接口抽象出来),但CDll为了测试,并没有实现类似的接口。

假设ADll和BDll实现了方法makeStr,CDll没有实现这个方法。

由于.NET的强大的反射机制,实现这些功能并不困难。

主体程序中调用Dll指定方法的代码:

         private   void  btnInvoke_Click( object  sender, System.EventArgs e)
        
{
            lstValue.Items.Clear();
            DirectoryInfo d 
= new DirectoryInfo("Dlls");  // 目录和当前EXE在同一个目录下
            foreach (FileInfo file in d.GetFiles("*.dll"))
            
{
                
string pathName = d.FullName + "/" + file.Name;
                
// 根据文件名获取程序集信息
                Assembly assembly = Assembly.LoadFrom(pathName);                
                lstValue.Items.Insert(
0,assembly.FullName + "的调用结果:");
                
try 
                
{
                    
foreach (Type t in assembly.GetTypes())
                    
{
                        Object obj 
= t.InvokeMember(null,
                            BindingFlags.Public 
| BindingFlags.Instance | BindingFlags.CreateInstance,
                            
null,null,null);
                        
string s = (string)t.InvokeMember("makeStr",
                            BindingFlags.Public 
| BindingFlags.InvokeMethod | BindingFlags.Instance,
                            
null,obj,null);
                        lstValue.Items.Insert(
0,s);

                    }

                }
 
                
catch (Exception ex)
                
{
                    lstValue.Items.Insert(
0,ex.ToString());
                }

            }

        
        }


ADll相关代码:
using  System;

namespace  ADll
{
    
/// 
    
/// Class1 的摘要说明。
    
/// 

    public class AClass
    
{
        
public AClass()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
        }


        
public string makeStr()
        
{
            
string retStr;
            retStr 
= "ADll make String";
            
return retStr;
        }

    }

}

BDll相关代码:
using  System;

namespace  BDll
{
    
/// 
    
/// Class1 的摘要说明。
    
/// 

    public class BClass
    
{
        
public BClass()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
        }


        
public string makeStr()
        
{
            
string retStr;
            retStr 
= "BDll make StringModifyAdd..ok2";
            
return retStr;
        }


    }

}
CDll相关代码:
using  System;

namespace  CDll
{
    
/// 
    
/// Class1 的摘要说明。
    
/// 

    public class CClass
    
{
        
public CClass()
        
{
            
//
            
// TODO: 在此处添加构造函数逻辑
            
//
        }


        
public string makeStr2()
        
{
            
string retStr;
            retStr 
= "cDll make StringModify";
            
return retStr;
        }


    }

}
机制测试:
1.先将ADll,BDll编译通过放到Dlls下面,运行testReadDll调用makeStr结果如下:

2.不需要退出testReadDll,将ADll删除,运行testReadDll调用makeStr结果如下:

3.不需要退出testReadDll,将ADll和CDll再次放入Dlls,运行testReadDll调用makeStr结果如下:

4.那么如果ADll和BDll增加一个副本又如何呢?
  不需要退出testReadDll,为ADll和BDll增加一个副本在Dlls如下图:

运行testReadDll调用makeStr结果如下:



小结:
由此可以看出,这样的机制是十分灵活的,只要将业务相关的Dll放入这个目录下面就可以了。
另外,对于副本的调用结果是一样的,当然这些可以在程序中再做一些限制,避免重复调用。
调用的顺序和时间规则也可以在程序中做定义或者用一个配置文件来限制。


这里下载相关代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值