在运行时加载程序集并使用Activator.CreateInstance()创建实例

时间:2012-09-07 11:50:30

标签: c# .net reflection

我正在尝试在运行时加载程序集,我不确定为什么我不能使用静态Activator.CreateInstance()在程序集中创建类型的实例。它适用于Assembly.CreateInstance()

string assemblyFilename = "MyAssembly.dll";
string assemblyName = "MyAssembly";
string typeName = "MyAssembly.MyType";

FileInfo fileInfo = new FileInfo(assemblyFilename);

这有效:

var assembly = Assembly.LoadFrom(assemblyFilename);
Form form = (Form)assembly.CreateInstance(typeName);

但这不起作用:

Assembly.LoadFrom(assemblyFilename);
Form form = (Form)Activator.CreateInstance(assemblyName, typeName).Unwrap();

抛出FileNotFoundException:

  

无法加载文件或程序集“MyAssembly”或其中一个   依赖。系统找不到指定的文件。

修改

在这两种情况下,在Assembly.LoadFrom()调用之后,当我查看AppDomain.CurrentDomain.GetAssemblies()时,我可以看到我的程序集已被加载。

4 个答案:

答案 0 :(得分:5)

您可以使用路径调整文件

var path = Assembly.GetAssembly(MyType.GetType()).Location;
var thisAssembly= Assembly.LoadFrom(path);

var TypeName = "";
Type type = thisAssembly.GetType(TypeName);
object instance = Activator.CreateInstance(type);

答案 1 :(得分:3)

您必须先将程序集加载到当前的AppDomain中:

AppDomain.CurrentDomain.Load(File.ReadAllBytes(assemblyFileName));
编辑:这有用吗?

Form form = (Form)Activator.CreateInstance(Type.GetType(typeName))

答案 2 :(得分:1)

尝试编辑原始答案,但我没有得到作者的回复。所以,如果有人需要这个,这里是适合我的代码

System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH"));  
Form form = (Form)assembly.CreateInstance("FullNameSpace.ClassName");

答案 3 :(得分:0)

这是A Khudairy的答案的变体,允许传入输入参数来访问特定的构造函数,加上他的答案的这种变化解决了我所遇到的问题,并且字面上一直在搜索和关闭几个星期现在试图解决(许多赞美他的分享答案)。

我的问题是我想将.NET 3.5 dll加载到.NET 4.6的新应用程序中,但那些旧的dll使用了第三方控件,这些控件看起来使用了CAS策略。我从第三方控件中得到一个错误,说我需要上交app.config,如果我这样做,我可以加载并运行文件就好了,如果它们在我的本地计算机上,但如果我试图加载它们来自我需要做的网络驱动器,然后我收到了FileIOPermission错误。

尝试使用loadFromRemoteSources和useLegacyV2RuntimeActivationPolicy运行NetFx40_LegacySecurityPolicy的组合,并尝试了几种不同的方法,例如Activator.CreateInstance(),它通常适用于我,尝试创建一个沙箱(虽然我不知道我是否正确地做到了)但除了下面之外什么也行不通。请注意,我的用户控件也基于基类。我在授予访问网络驱动器权限之前运行了一些CAS命令提示符命令,我的应用程序应该完全信任。无论如何,它看起来并不像我尝试过的任何方法,除了这个方法迄今为止对我有效。

代码修正:

object dllUserControl = null;
System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH"));  
dllUserControl = assembly.CreateInstance("FullNameSpace.ClassName",true,BindingFlags.Default,null,constructorParams[],null,null);

...之后我可以根据需要将对象(我的基类)转换为以后在其自己的表单/窗口中启动它。