动态加载DLL(Dynamic loading of DLL)
我有一个需要使用大量插件的程序。
每个插件必须支持一个非常基本的接口,这个接口是在一个DLL中定义的(为简单起见,IBaseComponent)。
每个插件都将位于特定目录(AppDirectory \ plugin \ plugin-type)中。 每个插件都可以具有该插件的dll(AppDirectory \ plugin \ plugin-type \ plugin-name.dll)的任何名称。
所以我需要检查每个插件子目录,找到每个拥有支持IBaseComponent接口的类的插件,实例化类并调用插件中的某些函数。
好吧,一切都很好,这些都不是特别困难。 但问题是我似乎遇到了一些奇怪的问题。
每个插件需要在单独的插件文件夹中有Base.dll文件(而不仅仅是在将要加载插件的程序中),并且似乎我在动态加载dll时遇到了很多错误和警告,这些dll也有需要加载。
我在用着:
pluginModule = System.Reflection.Assembly.ReflectionOnlyLoadFrom(PathToAssembly);
为了抓住插件DLL并使用:
types = moduleAssembly.GetTypes();
以便获取dll中包含的类型。 我遍历这些类型并检查单个类型是否为IBaseComponent接口(表示这是对加载类有效的):
if (type.GetInterface("FrameworkNameSpace.IBaseComponent") != null) //it's of the IBaseComponent interface
后来,为了从dll中实际创建一个类的实例,我使用:
pluginModule = System.Reflection.Assembly.LoadFrom(PathToAssembly);
然后使用:
types = component.GetTypes();
为了获得模块中的类型,然后选择并加载支持与上述相同的接口的类。
这个问题似乎在我使用时出现:
types = component.GetTypes();
实际上试图加载类时,而不是简单地看它。 (因此,我对LoadFrom和ReflectionOnlyLoad的不同用法)
我在GetTypes调用(第二次插入,但从来没有第一次!)收到的异常是:
{"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information."}
LoaderExceptions属性如下所示:
{"The specified module could not be found. (Exception from HRESULT: 0x8007007E)":null}
我不确定为什么会发生这种情况。 该DLL位于插件文件夹中,并且包含IBaseComponent接口的DLL也位于每个插件目录中。 我是否以这种错误的方式去做?
我还需要在每个plugin子目录中保存一个包含IBaseComponent的DLL的副本,以及程序本身使用的DLL的副本,还是我做了一些不正确的事情,这会让我去除这个需求?
我知道MEF是我想用的,但不幸的是,因为我需要在.net 2.0上支持这个功能,所以我无法使用MEF。
I have a program which needs to use a large number of plugins.
Each plugin must support a very basic interface, this interface is defined in a DLL (IBaseComponent for simplicity of question sake).
Each plugin will be in a specific directory (AppDirectory\plugin\plugin-type). Each plugin can have any name for the plugin's dll (AppDirectory\plugin\plugin-type\plugin-name.dll).
So I need to check through each plugin subdirectory, find each plugin that has a class which supports the IBaseComponent interface, instantiate the class and call some functions on the plug in.
ok, all fine and dandy, none of this is particularly hard. The problem though is that I seem to be running into some weird issues.
Every plugin needs to have the Base.dll file in the individual plugin folders (instead of just in the program that will be loading the plugin) and also it seems that I get many errors and warnings around dynamically loading a dll which have dll's that also need to be loaded.
I'm using:
pluginModule = System.Reflection.Assembly.ReflectionOnlyLoadFrom(PathToAssembly);
in order to grab the plugin dll and using:
types = moduleAssembly.GetTypes();
in order to grab the types contained within the dll. I am iterating over the types and checking if the individual type is of the IBaseComponent interface (signifying this is a valid to load class) with:
if (type.GetInterface("FrameworkNameSpace.IBaseComponent") != null) //it's of the IBaseComponent interface
Later, in order to actually create an instance of the class from the dll I use:
pluginModule = System.Reflection.Assembly.LoadFrom(PathToAssembly);
and then use:
types = component.GetTypes();
In order to get the types within the module then select and load the class which supports the interface same as above.
The problem seems to be on when I use:
types = component.GetTypes();
When actually trying to load the class, Instead of simply looking at it. (Hence my different usage of LoadFrom and ReflectionOnlyLoad)
The Exception I receive on the GetTypes call (on a second plug in, but never the first!) is:
{"Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information."}
With the LoaderExceptions property as:
{"The specified module could not be found. (Exception from HRESULT: 0x8007007E)":null}
I'm unsure why this occurs. The DLL is in the plugin folder, and the DLL containing the IBaseComponent interface is also in every one of the plugin directories. Am I going about this the wrong way?
Also is it required for me to keep a copy of the DLL containing IBaseComponent within each plugin subdirectory as well as the one used by the program itself, or am I doing something incorrectly that would allow me to remove this requirement?
I am aware of MEF which is what I wanted to use but unfortunately because I am required to support this on .net 2.0 I am unable to use MEF.
原文:https://stackoverflow.com/questions/5123170
最满意答案
有反编译.class文件的工具,例如JAD http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler )
从这个意义上讲,如果您要分发类文件,我不会说java是安全的。 但是,您可以采取一些措施,例如使用ProGuard等混淆器(http://proguard.sourceforge.net/)
There are tools to decompile .class files, such as JAD http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler)
In that sense, I wouldn't say java is secure if you're distributing your class files. However, there are measures you can take such as using an obfuscator such as ProGuard (http://proguard.sourceforge.net/)
相关问答
更多-
有反编译.class文件的工具,例如JAD http://en.wikipedia.org/wiki/JAD_(JAva_Decompiler ) 从这个意义上讲,如果您要分发类文件,我不会说java是安全的。 但是,您可以采取一些措施,例如使用ProGuard等混淆器(http://proguard.sourceforge.net/) There are tools to decompile .class files, such as JAD http://en.wikipedia.org/wiki/JA ...
-
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
如何从java中的.java文件创建一个“java.lang.Class”对象(How to create a “java.lang.Class” object from a .java file in java)[2022-07-22]
java 6 onwards为编译器提供了api: http : //www.javabeat.net/2007/04/the-java-6-0-compiler-api/ 上面的链接包括一个例子。 这里是另一个例子 - http://www.java2s.com/Code/Java/JDK-6/JavaCompilertoolshowyoucancompileaJavasourcefrominsideaJavaprogram.htm 编译后加载文件使用类加载器。 http://tutorials.jenk ... -
首先,您需要引用列表,否则它们将被评估,并且它们的第一个元素被视为要调用的函数,因此异常: (1,2,5) ;; => java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn 报价将帮助您获得包含数字的列表: '(1,2,5) ;; => (1 2 5) 不使用元素分隔符(例如, )也更加惯用,你可以看到上面打印的表格( (1 2 5) )。 由于这似乎是一个练习,我将让你解决你的merge功能中的其 ...
-
您可以这样检查:/ for properties / YourClass *arrObj=[YourClass new];//your target class where you wnat to check NSString *propertyName=@"samllArray";//this is what you will check in class YourClass if([arrObj respondsToSelector:NSSelectorFromString(propertyName)] ...
-
你不能用ldc获得java.lang.reflection.Method 。 对CONSTANT_MethodHandle执行ldc会生成一个MethodHandle 。 这些方法句柄可用于执行相关代码(尽管它的名称,它不限于方法),您可以查询其参数类型。 但是你无法将它转换为反射Method 。 虽然您可以执行反向操作,但将java.lang.reflection.Method转换为java.lang.invoke.MethodHandle 。 由于java.lang.invoke.MethodHandl ...
-
因此BalusC没有写出答案。 这是他的答案: 显然项目没有建成。 您能确保选中Project> Build Automatically选项吗? 构建项目解决了问题。 Hence BalusC doesn't write an answer. Here is his answer: Apparently the project is not built. Can you ensure that the option Project > Build Automatically is checked? Buil ...
-
为什么0代表java.lang.Class.forName0?(Why does the 0 represent in java.lang.Class.forName0? [duplicate])[2021-05-15]
请注意,此方法的源代码的可见性标记为private 。 /** Called after security check for system loader access checks have been made. */ private static native Class> forName0(String name, boolean initialize, ClassLoader loader, ... -
在这个类声明中 public class ProductTypeDaoImpl extends GenericDaoImpl implements ProductTypeDao 您使用GenericDaoImpl和ProductTypeDao作为原始类型。 首先阅读为什么不应该使用它们。 您使用原始类型的事实会导致问题 ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass(); ...
-
java.lang.class
和Cls有什么区别?(What is the difference between java.lang.class [2022-07-14]and just Cls? [duplicate]) Class和T之间的区别在于Class Class 表示关于T元数据。 您可以查找T的方法和字段,还可以通过调用newInstance方法创建新实例。 就创建Class 对象而言,最简单的方法是使用MyClass.class语法,例如 Class tr = TermlistRequest.class; 也可以通过动态解析类来获取Class (但不是Class )对象。 The difference between Class and T i ...