可选的库引用是否可行? (对于可修改的Mods)

时间:2016-11-20 08:53:38

标签: c# .net visual-studio

有什么方法可以告诉Visual Studio为我构建一个.dll,只有当它存在但仍然作为引用加载另一个引用(托管)库时才会加载它?

基本上我希望能够从外部lib中的类继承,并且只有当外部类存在时才会初始化它。

更长的解释:

  • 我使用modding api制作游戏(通过Assembly.LoadFrom)
  • 我希望mods可以修改。假设我有2个mods Mod A和Mod B. Mod A提供了一个静态注册表来添加额外的功能。所以在Mod B中我正在检查是否加载了Mod A,如果是,则使用Mod As静态注册表来注册我的添加。
  • 问题是,为了在没有编译错误的情况下这样做,我必须在Mod Studio的Visual Studio项目中添加Mod A作为引用 - 如果Mod A不存在则导致Mod B无法加载。但它应该是一个可选的参考:/

类似于"懒惰图书馆参考"将是完美的 - 只有在实际需要时才加载lib引用。

2 个答案:

答案 0 :(得分:2)

您应该阅读MEF的工作原理(Managed Extensibility Framework),因为它是考虑到这种插件方案而设计的。

这也是你应该考虑如何围绕接口而不是继承来描述你的抽象的地方。我确信你可以用动态类型和反射来做一些聪明的事情,但我也认为这很可能会变得复杂,因此容易出错。

您还可以使用Lazy<T>来确保只在需要时通过外部依赖项的延迟实例化来加载内容。您也不必为这些插件dll添加静态引用。您可以扫描目录以查找实现抽象接口定义的库和类型。

我还有点担心你为什么要让一个抽象依赖于另一个抽象(Mod B检查Mod A),这在某种程度上听起来有问题 - 一个&#34;漏洞&#34;抽象可以这么说。

如果你真的必须让这些插件合作在一起,你可以使用自定义属性方法,这样mod就可以声明一个依赖。

public class ModDependency : Attribute
{
    public string DependsOn { get; set; }
}

但最终您将在主应用程序代码中进行一些协调,然后在运行时提供对这些插件的实例引用。

答案 1 :(得分:0)

“.Net中的程序集是由CLR按需加载的。通常,在使用JIT程序的方法之前不会尝试组装加载,该方法使用该程序集中的类型。” (来自不同的SO Answer

我知道了!显然,我可以应用我的可选依赖方法!

我发现问题是由于我加载这些mod的方式而产生的。我正在迭代所有程序集类型,检查实现IMod的任何类,这显然导致有问题的类被加载,并且需要CLR加载依赖项。

而不是调用assembly.GetTypes()我现在调用assembly.GetExportedTypes()并将有问题的类声明为内部。现在,如果依赖项不存在,它永远不会被加载。