【问题标题】:C# Controlling dll accessC# 控制 dll 访问
【发布时间】:2011-01-26 15:27:09
【问题描述】:

我有一个使用插件架构的程序。当初始表单加载时,它会扫描当前目录,查询每个 dll 并获取一些基本数据显示给用户。

在使用该程序时,该软件通常需要要求 dll 执行一些工作。

我的问题是,当程序最初检查 dll 文件时,我应该保留对每个 dll 对象的引用以供将来使用,还是应该每次查询 dll 文件并在需要时创建对象?

如果它是第一个,那么最好的方法是保留从公共接口派生的未确定数量的对象列表,然后知道在需要时引用哪个对象?

谢谢。

【问题讨论】:

  • 我会说如果需要保存并在需要时创建:)。

标签: c# dll


【解决方案1】:

使用第一个你可以创建一个

List<IYourCommonInterface> pluginDlls

然后只是

pluginDlls.Add(dllReference);

编辑

使用字典的替代方法,请注意,这需要您为字典提供某种 ID,您可以使用该 ID 来识别 dll。

Dictionary<SomeIDField, IYourCommonInterface> pluginDlls

pluginDlls.Add(dllRefrence);

【讨论】:

  • (1+) 可能是字典...这样您就可以轻松识别/访问每个资源
【解决方案2】:

大多数应用都会在加载时进行检查。

我不会存储接口列表。如果您确实存储它们,那么您会遇到程序集消失或以某种方式更新的可能性。无论如何,此时您都需要“刷新”它们。

【讨论】:

    【解决方案3】:

    一旦您加载了程序集并获得了 System.Reflection.Assembly 的实例进行反射(使用 Assembly.Load()、Assembly.LoadFrom()、Assembly.LoadFile() 等),程序集就会被加载.引用MSDN on the subject:

    ...可以...可以将特定程序集加载到当前应用程序域中 在运行时...不卸载就无法卸载单个程序集 包含它的所有应用程序域。 即使程序集退出 范围,实际的程序集文件将保持加载,直到所有应用程序域 包含它的内容将被卸载。 [强调我的]

    因此,如果您想在真正需要它们之前卸载 DLL,您将不得不创建一个新的应用程序域,然后将其卸载。加载它们并完成它更容易。如果您愿意,您可以保留 assemply 引用,但如果您再次调用 Assembly.Load(),它实际上不会加载程序集:它只会获取对先前加载的程序集的引用。

    【讨论】:

      【解决方案4】:

      如果您在查找和加载 DLL 时遇到了麻烦,通常您会希望保留它们。这主要取决于 DLL 使用了多少资源以及您的应用如何使用 DLL。

      我假设您在这里使用 LoadAssembly。您可以只存储对使用某种映射加载的程序集的引用。甚至是您迭代的列表。

      也许如果您提供更多详细信息,我们可以为您提供更好的帮助。

      【讨论】:

      • 实际上,在程序加载时,程序会查询 dll 并向用户显示它们的标识符/名称。然后用户可以选择一个和一些外部数据,然后 dll 知道如何处理这些数据。
      • 因此,有时您必须创建一个在 DLL 中定义的类的实例,但它实现了您在主应用程序中定义的通用插件接口。有多种方法可以做到这一点。例如,在加载时,DLL 可以在主应用程序中的某种注册表中注册自己。或者您可以使用反射查找特定实例的类名,从 DLL 派生名称。有关示例,请参阅 social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/…
      • 我认为识别插件类的更惯用的解决方案是接口和属性的组合。加载程序集后,遍历其中的所有类型并选择那些具有您的属性并且也直接或间接实现您的接口的类型。例如,查看 PowerShell 识别 cmdlet 的方式。
      猜你喜欢
      • 2013-01-27
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-16
      • 2019-02-11
      • 1970-01-01
      • 2011-12-18
      相关资源
      最近更新 更多