如何使用接口从dll内的方法调用和检索数据? [英] How to Invoke and retrieve data from a method inside a dll using interface?

查看:72
本文介绍了如何使用接口从dll内的方法调用和检索数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用界面从dll内的方法调用和检索数据?

INFO:

我们使用的是Windows窗体和sql server2005,我们将数据作为xml传递并使用存储过程。在应用程序层客户端不提供互联网,意味着业务和数据库层具有互联网连接。

我们将业务对象类文件放置为dll在具有互联网连接的客户端机器的共享文件夹中。我可以调用dll内的函数,通过dll内的接口类传递参数,并在业务层上检索输出

我们有接口类IGetData

How to Invoke and retrieve data from a method inside a dll using interface?
INFO:
we are using windows forms and sql server2005,we pass data as xml and uses stored procedures .In the application layer client is not providing internet,mean while the business and database layer have internet connectivity.
we have placed business object class files as dll in a shared folder of client machine which has internet connectivity.how can i call a function inside the dll ,pass parameters through an interface class inside the dll and retrieve the output
on the Business layer we have an interface class "IGetData"

namespace WNHRP01BO
{
   public interface IGetData
    { 
        string GetData(string Xml, string ClassName, string Mode);
    }
}



业务层中的类文件函数GetData ,将被调用的如下所示


class file in the Business layer having function "GetData" ,which is to be called is shown below

namespace WNHRP01BO
{
    public class hb007001C0 : WNHRP01BO.IGetData
	{
		PLABS.DbProvider _objDb = PLABS.DbProvider.MSSql;
		public hb007001C0()
		{
			
		}
		#region IGetData Members
		public string GetData(string Xml,  string AddParams,string Mode)
		{
			String retXml = string.Empty;
			if (Mode == "I")
				{
					PLABS.DAL objDbHelper = new PLABS.DAL();
					retXml= objDbHelper.insertSP("hb007001F0_IU", Xml, this._objDb);
				}
            return retXml;
     
		}
		#endregion
	}
}





CallBOCommon应用层中的一个类,通过它使用webservice连接业务层或参考项目如下所示



"CallBOCommon" a class in application layer ,through which the business layer is connected either using webservice or referenced project as shown below

namespace UtilsApp
{
    public class CallBOCommon
    {
        public String CallWS(String Xml, String ClassName, String Mode)
        {
          //////calling from referenced business object project "WNHRP01BO"
          //// Type tp = Type.GetType(ClassName);
//String retDat = (((WNHRP01BO.IGetData)Activator.CreateInstance(tp)).GetData(Xml, "", Mode));
     ////   return retDat;

       //////////calling webservice
         //Connector.AuthWS obj = new Connector.AuthWS();
         //Xml = PLABS.Utils.Compress(Xml);
 //String retDat = obj.CallWS(Xml, ClassName, Mode, "http://somehostingserver.in/service.asmx");
          //return retDat;

///actually what i am trying to impliment is to replace below lines 
//String retDat = (((WNHRP01BO.IGetData)Activator.CreateInstance(tp)).GetData(Xml, "", Mode));
//return retDat;with ur provided code 
//but i dont know how to specify the type of Activator.CreateInstance(tp) 
//as (WNHRP01BO.IGetData) while loading from dll

  //////i am getting class name as "WNHRP01BO.hb007001C0,WNHRP01BO"
 //////BOClass =WNHRP01BO.hb007001C0
 string BOClass = ClassName.Split(',')[0].ToString();
/////////reading from dll on the shared folder of client machine
 Assembly a = Assembly.LoadFile(@"D:\DLL\live hrp\WNHRP01BO.dll");
 var aTypes = a.GetTypes();
 Type t = aTypes.FirstOrDefault(tp => tp.FullName == BOClass);
// how to specify the type of Activator.CreateInstance(tp) as (WNHRP01BO.IGetData)
 object obj = Activator.CreateInstance(t);
/////cant list GetRuntimeMethods() from type
     MethodInfo MI = t.GetMethods().FirstOrDefault(m1 => m1.Name.IndexOf("GetData") > 0);
 var retVal = MI.Invoke(obj, new object[] { Xml, ClassName, Mode });
////am getting value Of MI as Null
//////what am i missing here?

        }

    }

推荐答案

我认为你可以执行以下操作:



I think you can do something like the following:

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

namespace Test_Reflection2
{
    class Program
    {
        static void Main(string[] args)
        {
            // load assembly
            Assembly l = Assembly.LoadFile(@"d:\tmp\Test_ReflectionSampleLib.dll");
            // types in that assembly
            var ts = l.GetTypes();

            // find interface
            Type i = ts.FirstOrDefault(t1 => t1.Name == "IGetData" && t1.IsInterface);
            // find class which implements interface
            Type c = ts.FirstOrDefault(t1 => t1.IsClass && t1.GetInterface("IGetData") != null);
            // create an instance of class
            object o = Activator.CreateInstance(c);
            // get method. not good way to find the method!!
            MethodInfo mi = c.GetRuntimeMethods().FirstOrDefault(m1 => m1.Name.IndexOf("IGetData.GetData") > 0);
            // invoke it
            var retval = mi.Invoke(o, new object[] { string.Empty, string.Empty, string.Empty });
            Console.WriteLine(retval);
        }
    }
}


在您的应用程序层中右键单击项目并选择添加引用然后选择位置WNHRP01BO.dll和确定。

现在在CallBOCommon类中导入名称空间WNHRP01BO并访问类hb007001C0。

为此类创建对象并调用getdata()通过这个对象。



谢谢,

-RG
In your Application Layer right click on the project and select add reference then choose location of "WNHRP01BO.dll" and ok.
Now in CallBOCommon class import the namespace WNHRP01BO and access the class "hb007001C0".
Create object for this class and call getdata() through this object.

Thanks,
-RG


试试这个,我测试了它是有效的。

使用动态来尝试防止需要汇编参考和&类型转换。



Try this, I have tested and it works.
using dynamic to try an prevent need for Assembly references & Type casting.

public object CallWS(string Xml, string ClassName, string Mode) {
    try {

    Assembly a;
    if ((a = Assembly.LoadFile(@"D:\DLL\live hrp\WNHRP01BO.dll")) != null) {
        var aTypes = a.ExportedTypes.ToArray();

        Type t;
        string BOClass = ClassName.Split(',')[0].ToString();
        if ((t = aTypes.FirstOrDefault(tp => tp.FullName == BOClass)) != null) {
            object obj = Activator.CreateInstance(t);
            object igd = (dynamic)obj.GetType().GetInterface("IGetData");
            object value;

        //option 1:------------------------------------>>
            value = ((dynamic)igd).InvokeMember(
                            "GetData", 
                            BindingFlags.InvokeMethod | 
                            BindingFlags.Instance | 
                            BindingFlags.Public,
                            null,
                            obj,
                            new object[] { Xml, ClassName, Mode }
                    );

        //option 2:------------------------------------>>
            MethodInfo mi = ((dynamic)igd).GetMethod("GetData");
            value =  mi.Invoke(obj, new object[] { Xml, ClassName, Mode });

            return value;
        }
    }

    return null;
    } 
    catch { return null; }
}


这篇关于如何使用接口从dll内的方法调用和检索数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆