【问题标题】:MEF circular dependencyMEF 循环依赖
【发布时间】:2012-03-17 18:59:51
【问题描述】:

假设我们有两个相互依赖的组件(间接地,通过接口):

public interface IAlice { ... }
public interface IBob { ... }

[Export(typeof(IAlice)), PartCreationPolicy(CreationPolicy.NonShared)]
class Alice : IAlice
{
    [Import]
    private IBob Bob { get; set; }
    ...
}

// could be defined in some assembly developed by another team
[Export(typeof(IBob)), PartCreationPolicy(CreationPolicy.NonShared)]
class Bob : IBob
{
    [Import]
    private IAlice Alice { get; set; }
    ...
}

这会导致合成失败:合成失败,因为它没有在“100”次迭代内完成。这很可能是由标记为非共享创建策略的部分的依赖关系图中的循环引起的。

我知道我可以通过延迟声明导入,但是当我需要我的 Alice 引用 Bob 和 Bob 引用 Alice 的同一个实例时,将按需创建导入。我原以为 CompositionContainer 会在一次合成操作中解决此类循环,但显然情况并非如此。

我不能将部件声明为共享,因为每个容器不需要一个 Alice 和 Bob。我只需要在一个组合操作中完成时将此类依赖关系图创建为一个整体。有什么解决办法吗?

UPD。添加了一些说明。

【问题讨论】:

  • 您在对我的回答的评论中提到 Alice 和 Bob 可以由不同的各方开发。如果是这种情况,那么 Alice 和 Bob 都不知道存在循环依赖,因此他们都不能指望他们都引用同一个实例。这表明你的懒惰方法是可以接受的。我错过了什么?
  • 是的,你是对的,懒惰的方法是可以接受的。我更喜欢允许惰性和非惰性导入,但似乎 MEF 无法处理涉及非共享部分的非惰性循环引用。因此,我们将所有属性导入限制为惰性导入。感谢您的帮助!

标签: c# mef circular-dependency


【解决方案1】:

为什么不让 Alice 通过 ctor 注入导入 IBob,然后显式设置 Bob 的 Alice 属性(即 Bob 对 Alice 使用属性注入)?

【讨论】:

  • (我不应该将这些注入属性声明为公开的,抱歉——已修复)。关键是 Alice 和 Bob 是由不同的人开发的。爱丽丝不知道鲍勃使用它,鲍勃也不知道爱丽丝使用它。我们不允许ctor注入,因为它会导致原则上无法解决这种循环依赖的情况,所以我们被属性注入卡住了。
  • Somebody 必须了解循环依赖。再次公开属性,但删除 Import 属性。现在定义Charlie(IAlice alice, IBob bob) { alice.Bob = bob; bob.Alice = alice; }。为 Alice 和 Bob 提供 Charlie 的公共属性,并确保其他人只能通过这些属性访问 Alice 或 Bob。
  • 感谢@Akash 的建议,但我们不能那样做。在我们的例子中,Alice 和 Bob 可以是不同方开发的插件。而且我们不知道他们实施的任何细节。 必须有人理解循环依赖。 — 我希望这个 Somebody 可以是 MEF。只有 MEF 完全了解组件之间的所有内部依赖关系。
猜你喜欢
  • 2010-09-12
  • 2021-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多