从特定文件夹动态加载DLL

本文关键字:加载 DLL 动态 文件夹 | 更新日期: 2023-09-27 18:20:59

目前,我有以下代码:

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的对象我尝试了大约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的方式不对,有两个参数。我该怎么办?

从特定文件夹动态加载DLL

这是运行时"从特定文件夹动态加载.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();
        }
    }
}

这花了我一段时间才解决,所以我希望它有一些用处。。。

一旦您调用此线路

var shellViewLibrary = Assembly.LoadFrom(Path.Combine(_DllsPath, _DllShellView)); 

程序集已加载到内存中。只要您正确地指定了类型,那么您就可以使用Activator.CreateInstance来创建类型。即:没有必要进一步指定,其中是类型。

关于Activator,MSDN的CreateInstance方法可以接受System.Type。我只想在if语句中使用这个方法:

Activator.CreateInstance(Type type);

为了调试它,我会尝试先创建类型,然后将其传递给CreateInstance。您可能会发现类型创建本身失败(由于未解析的程序集)或该类型的实例化失败(由于构造函数中的异常)。乍一看,这里的代码似乎是正确的:

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.无关

你能试着发布内部异常以更好地了解问题是什么吗?

查看MEF和Prism。MEF是一个依赖注入库,可以帮助实现这一点。您可以从特定文件夹加载所有依赖项,并使其动态加载。

Prism是一种利用依赖注入的模式,它与MEF非常配合,可以动态加载库

如果您试图从应用程序外部的DLL创建具有Activator类的类型,则需要首先在应用程序域内加载此DLL。最简单、最快捷的方法是使用Assembly.LoadFile方法。

有关该方法的更多信息,请点击此处:http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfile.aspx

正确加载程序集后,可以使用Activator从DLL内的类型创建实例。我们使用这个机制在应用程序中运行自定义代码。

我不知道你说的是什么意思

在特定文件夹(构建文件夹之外)中创建一个类型为type的对象

类型仅存在于程序集中路径与.NET中的类型完全无关

假设所说的"路径"实际上是指"命名空间",这意味着你不知道类型存在于哪个命名空间中。您已经在代码中加载了程序集。使用反射检查程序集以查找要查找的类型。然后将代表您要查找的类型的Type对象传递给Activator.CreateInstance