目前,我有这段代码:
var shellViewLibrary = Assembly.LoadFrom(Path.Combine(_DllsPath, _DllShellView));
IEnumerable<Type> types = shellViewLibrary.GetTypes();
foreach (Type type in types)
{
var typeIShellViewInterface = type.GetInterface(_NamespaceIShellView, false);
if (typeIShellViewInterface != null)
{
//here
}
}
问题在于我得到了//here
我希望使用Activator.CreateInstance
创建一个在特定文件夹中类型为type
的对象(即在build文件夹之外)
我尝试了大约20种不同的东西,其中大多数是这样的:http://msdn.microsoft.com/en-us/library/d133hta4.aspx
但都没有效果......
我尝试过的典型事情是:
object MyObj = Activator.CreateInstance(shellViewLibrary.FullName, type.FullName);
或
object MyObj = Activator.CreateInstance(Path.Combine(_DllsPath, _DllShellView), type.FullName);
我总是有不同的例外,最常见的是:
XamlParseException
我觉得我没有以正确的方式使用Activator.CreateInstance和2个参数。我该怎么办?
答案 0 :(得分:8)
这是“在运行时从特定文件夹动态加载.dll”的示例。
// Check if user has access to requested .dll.
string strDllPath = Path.GetFullPath(strSomePath);
if (File.Exists(strDllPath))
{
// Execute the method from the requested .dll using reflection (System.Reflection).
Assembly DLL = Assembly.LoadFrom(strDllPath);
Type classType = DLL.GetType(String.Format("{0}.{1}", strNmSpaceNm, strClassNm));
if (classType != null)
{
// Create class instance.
classInst = Activator.CreateInstance(classType);
// Invoke required method.
MethodInfo methodInfo = classType.GetMethod(strMethodName);
if (methodInfo != null)
{
object result = null;
result = methodInfo.Invoke(classInst, new object[] { dllParams });
return result.ToString();
}
}
}
这需要我一段时间才能解决,所以我希望它有一些用处...
答案 1 :(得分:7)
一旦你拨打这一行
var shellViewLibrary = Assembly.LoadFrom(Path.Combine(_DllsPath, _DllShellView));
程序集已加载到内存中。只要您从中正确指定类型,就可以使用Activator.CreateInstance来创建类型。 ie:没有必要进一步指定类型所在的 where 。
关于Activator,来自MSDN的CreateInstance方法可以接受System.Type。我会在你的if语句中使用这个方法:
Activator.CreateInstance(Type type);
我要尝试调试它的方法是首先创建类型,然后将其传递给CreateInstance。您可能会发现Type创建本身失败(由于未解析的程序集)或该类型的实例化(由于构造函数中的异常)。乍一看,您的代码似乎是正确的:
foreach (Type type in types)
{
var typeIShellViewInterface = type.GetInterface(_NamespaceIShellView, false);
if (typeIShellViewInterface != null)
{
try
{
// I assume you are calling this line at the point marked 'here'.
// To debug the creation wrap in a try-catch and view the inner exceptions
var result = Activator.CreateInstance(type);
}
catch(Exception caught)
{
// When you hit this line, look at caught inner exceptions
// I suspect you have a broken Xaml file inside WPF usercontrol
// or Xaml resource dictionary used by type
Debugger.Break();
}
}
}
在您的问题中,您指定获得XamlParseException
。听起来像我所讨论的类型是UserControl(或者指的是WPF Xaml资源文件),并且该Xaml文件中存在错误,即与您使用Assembly.Load或Activator.CreateInstance无关。
您是否可以尝试发布内部异常以更好地了解问题所在?
答案 2 :(得分:2)
答案 3 :(得分:0)
如果您尝试使用应用程序外部的DLL创建具有Activator类的类型,则需要首先在应用程序域中加载此DLL。 最简单,最快捷的方法是使用 Assembly.LoadFile 方法。
有关该方法的更多信息,请访问:http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfile.aspx
正确加载程序集后,可以使用Activator从DLL内部的类型创建实例。 我们使用此机制在我们的应用程序中运行自定义代码。
答案 4 :(得分:0)
我不确定你的意思是什么:
在特定文件夹(位于构建文件夹之外)创建类型为 type 的对象
类型仅存在于程序集中。 路径与.NET中的类型完全无关
我假设通过“path”你真的是指“命名空间”,这意味着你不知道该类型存在于哪个命名空间中。您已经在代码中加载了程序集。使用反射检查装配体以找到您要查找的类型。然后将代表您要查找的类型的Type
对象传递给Activator.CreateInstance