隐式创建位于依赖dll中的类的实例

时间:2015-05-05 20:28:37

标签: c# .net vb.net

假设您正在开发一个名为"ThirdParty.dll"的第三方DLL,它有一个名为JustTryToInstantiateMe的类。假设您的客户有一个引用"ThirdParty.dll"的EXE,或者EXE没有"ThirdParty.dll"的引用,但是如果以某种方式请求,EXE可以在PATH中找到"ThirdParty.dll"。您无法控制EXE,因为您是"Thirdparty.dll"的供应商,并且您只能修改DLL的功能。您的客户,即编写EXE的客户,同意引用您的DLL或将您的DLL放入PATH。没什么。

有没有办法在运行EXE时实例化JustTryToInstantiateMe而不显式使用new或调用静态/共享方法/字段/属性?

也许只是以某种方式使用静态/共享构造函数?也许在AssemblyLoad()事件?也许使用注册表?一个启动过程?寻找想法......

2 个答案:

答案 0 :(得分:1)

我知道如何执行此操作的最近方法是动态加载程序集,然后从您创建的类的实例调用方法。

以下是代码中c#的模板:

        //add using for system.reflection
        String className = "[NAME OF CLASS WITH FULL NAMESPACE GOES HERE]";
        String methodName = "[METHOD NAME GOES HERE]"
        String dllPath = "[FILE PATH FOR DLL GOES HERE]";

        Assembly assembly = Assembly.LoadFile(dllPath);
        Type type = assembly.GetType(className);
        MethodInfo method = type.GetMethod(methodName);
        object context = Activator.CreateInstance(type);

        //optionally set up parameters here
        object[] parameters = new object[0];
        String result = (String) method.Invoke(context, parameters);

例如,我可以像这样创建一个类(我知道,它是VB,但接下来是C#。

        Public Class my_class
            Private hello = "hello world"
            Public Function gethello()
                Return hello
            End Function
        End Class

然后在编译之后,我可以在C#中使用以下代码来做我认为你在问的问题:

        //using system.reflection
        String className = "mytestlibrary.my_class";
        String dllPath = "...mytestlibrary.dll";
        String methodName = "gethello";
        Assembly assembly = Assembly.LoadFile(dllPath);
        Type type = assembly.GetType(className);
        MethodInfo method = type.GetMethod(methodName);
        object context = Activator.CreateInstance(type);
        object[] parameters = new object[0];
        String result = (String) method.Invoke(context, parameters);
        //result is "hello world"

现在,如果你想做同样的事情,但是已经编译好的EXE文件,那么代码几乎没有什么不同,但你需要创建一个桌面/控制台应用程序来封装其他可执行文件并正确命名你的DLL。因此,在您的应用程序中,添加以下代码以从EXE中引用的DLL中获取类的实例。

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        String className = "My_Class";
        String ExePath = "[PATH TO EXE]";
        String methodName = "gethello";
        Assembly assembly = Assembly.LoadFile(ExePath);
        Type type = assembly.GetType(className);
        MethodInfo method = type.GetMethod(methodName);
        object context = Activator.CreateInstance(type);
        object[] parameters = new object[0];
        String result = (String) method.Invoke(context, parameters);

你也可以动态地将程序集加载到EXE中,但这有点棘手,所以我现在暂时将其保留在此处,除非你真的需要动态地将你的DLL加载到EXE中。

答案 1 :(得分:0)

从研究中我发现这个问题的简单答案是这是不可能的。简短的回答是,为了加载DLL中的类,需要通过某些东西引用类。如果一个DLL能够通过JUST在PATH中自我加载,这将带来各种安全问题。