【问题标题】:.Net Load Reference at runtime.Net 运行时负载参考
【发布时间】:2009-07-10 12:18:27
【问题描述】:

我有以下要求,

  • 我有 C#/.Net 控制台应用程序,它指的是“System.Data.Sqlite.dll”
  • 'System.Data.Sqlite.dll' 未在 GAC 中注册(我不想)
  • 我不想将它保存在保存可执行文件(.exe)的目录中。

  • 如何将“System.Data.Sqlite.dll”文件保存在其他目录,并在运行时安全地加载它,然后在应用程序代码中引用它? p>

【问题讨论】:

  • 拥有 .exe 所在的 dll 有什么问题?
  • 为什么不能将DLL保存在EXE目录下?这是依赖 DLL 的标准位置,.Net 无需您付出任何额外的努力就可以找到。
  • 这是 Windows 客户端(win forms)应用程序还是 Web 应用程序?
  • 我想做的,类似于插件加载。插件 dll 保存在 .exe 文件以外的不同目录中,我想在应用程序启动时加载它。

标签: .net reflection assemblies


【解决方案1】:

您可以使用手动装配分辨率来执行此操作。

您需要为当前 AppDomain 中的 AssemblyResolve 事件提供委托

AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += assemblyResolver.ResolveEventHandler;

当应用程序有任何无法解析的程序集引用时,它将调用此委托来解析程序集。 然后,您可以简单地返回代表请求的程序集:

Assembly assembly = Assembly.LoadFrom (assemblyPath);
return assembly;

希望对你有帮助

【讨论】:

    【解决方案2】:

    我不确定您为什么要再次执行此操作,这与最佳实践有偏差,但要回答您的问题: 你可以使用

    Assembly.LoadFrom Method (String path)
    

    来自System.Reflection 命名空间

    & 在 app.config 文件中有路径

    Assembly.LoadFrom on MSDN

    【讨论】:

    • 我无法添加 app.config 文件的路径,DLL 目录可能会在运行时更改。任何解决方法?
    • 为什么运行时dll目录会发生变化?
    • @Palani - 请您简要解释一下您的用例
    【解决方案3】:

    您可以在应用程序的配置文件中添加探测元素。这允许检查默认文件夹以外的其他文件夹是否有所需的库。见here

    出于安全原因,它仍然必须位于 exe 文件夹下。

    【讨论】:

      【解决方案4】:

      您可以使用 Assembly.LoadFrom(filename)

      但正如评论者指出的那样,我不明白您为什么要这样做?

      【讨论】:

        【解决方案5】:

        您需要结合使用 Assembly.LoadFromType.GetTypeSystem.Reflection 命名空间)加载您的 dll 和方法/strong> 和 Type.GetMethod

        这是一个关于如何使用反射从运行时加载的 dll 中动态调用方法的示例。

        static string DynamicMethodCall(string dllPath, string someClass, string someMethodName, object[] parameters)
                {
                    Assembly dll = Assembly.LoadFile(dllPath);
        
                    Type type = dll.GetType(someClass);
        
                    if (type == null)
                    {
                        Exception ex = new Exception("class not found");
                        throw ex;
                    }
        
                    MethodInfo method = type.GetMethod(someMethodName);
        
                    if (method == null)
                    {
                        Exception ex = new Exception("method not found");
                        throw ex;
                    }
        
                    if (parameters.Length >= 1)
                    {
                        object[] myparam = new object[1];
                        myparam[0] = parameters;
                        return (string)method.Invoke(null, myparam);
                    }
                    else
                    {
                        return (string)method.Invoke(null, null);
                    }
                }
        

        【讨论】:

          【解决方案6】:

          您可以将 DLL 作为嵌入式资源包含在您的 EXE 项目中,并且当您的应用程序启动时,您可以将 DLL 保存到您的 EXE 文件目录中(并在应用程序结束时将其删除,尽管我不知道是什么问题在于在 EXE 目录中有 DLL)。只要您在加载任何引用 SqlLite 的内容之前执行提取,这将起作用。

          更新:既然你想做插件式的 DLL,你可以把 DLL 保存在一个单独的目录中,并在应用程序启动时将它们复制到 EXE 文件夹中。

          【讨论】:

            【解决方案7】:

            除了 exe 文件之外,我看不到引用程序集的原因,但一种方法是将它们放在一个单独的目录中 在 exe 文件所在的目录下在 app.config 文件中找到并包含一个探测元素。

            【讨论】:

              【解决方案8】:

              你可以使用反射:http://msdn.microsoft.com/en-us/library/system.reflection.assembly.load%28VS.71%29.aspx

              由于性能,请小心。必须谨慎使用反射。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-01-17
                • 1970-01-01
                相关资源
                最近更新 更多