【问题标题】:Configure and expose a singleton to all modules in a MEF/PRISM application为 MEF/PRISM 应用程序中的所有模块配置和公开单例
【发布时间】:2011-03-24 18:45:41
【问题描述】:

我有一个使用 MEF 和 PRISM 的应用程序(只是一个测试)。

加载一些符合特定接口的导出非常容易 并将它们传递给正在加载的模块的构造函数,但我正在尝试做一些不同的事情。

当应用程序启动时,它会导入 IControllerClient 的实现。 然后需要配置创建的实例(例如通过 shell),然后 应用程序中的每个模块都应该可以访问它。

我不想在 Shell 或某些帮助程序类上拥有公共属性 这种情况可能会被认为是一种不好的做法......而且我不太喜欢它。

更新: 重新表述下面的问题

我们在现有框架中定义了许多接口, 通常这些是使用 MEF 加载到各种应用程序中的。

我能够将它们加载到 prism 应用程序的模块中,例如:

[ImportingConstructorAttribute()]
public HelloWorldView(IDataTransportService dataTransportService,
                      IMessageFactory messageFactory,
                      IDataFactory dataFactory,
                      IDataProcessor dataProcessor,
                      IDataCollector dataCollector)
{
        var client = new ControllerClient(dataTransportService,
                                          messageFactory,
                                          dataProcessor
                                          dataCollector);
}

在这种情况下,模块会创建一个有效的 ControllerClient 类实例。

但我不想将这些接口传递给构造函数,而是想要一个模块 像这样的构造函数:

[ImportingConstructorAttribute()]
public HelloWorldView(IClient client)
{
   this.client = client;
}

IClient 实现 (ControllerClient) 的构造函数具有 [ImportingConstructorAttribute()] 所以我希望注入依赖项 在这一点上自动...但是使用此代码,甚至永远无法到达构造函数。

我想要的是拥有一个 IClient 接口的实例,供以下人员使用 应用程序中的所有模块。 (我现在明白 Shared 是 MEF 导入的默认设置)。

最好的方法是什么?为什么我不能让模块构造函数使用 IClient, 如果我想以这种方式公开一个类的实例,如果它不知道 mef 怎么办?

那么在 mef/prism 应用程序中,你会在哪里定义这个可供所有模块使用的实例?这就是通常所说的服务吗(但我只能找到关于使用统一/棱镜公开服务的指南)。

我希望这次我能更好地解释我的问题。

更新 2: 由于默认是为 MEF 导入共享的,我可以在每个模块中导入 IClient 实现,但是我需要弄清楚为什么不注入依赖项

【问题讨论】:

  • 设置 PartCreationPolicy 有什么问题?在我看来,这正是您所需要的。
  • 我可能解释错了我的问题.. 我会尝试改写它,对不起

标签: c# prism mef


【解决方案1】:

对于 MEF,Shared 是默认设置,因此接口的每次导入都将解析为同一个实例。该实例的配置可以在类的构造函数中进行,或者您可以在您的“单例”服务类上实现IPartImportsSatisfiedNotification,这将在 MEF 完成解析您的类导入时回调。


阅读您更新的描述,听起来您无法在其构造函数中或在解析其 Imports 之后配置该类,因为您需要一些额外的上下文信息。如果是这种情况,您可以在 Shell 中手动配置该类,并在使用容器的 ComposeParts 方法创建导出后手动添加它。这将使您的“已配置”实例成为用于解析您已应用于该类的任何 [Export] 标记的实例。当然,在通过依赖于实例的容器构造任何其他内容之前,您必须这样做。

【讨论】:

  • 我会试试的,听起来很合理:)
  • 像魅力一样工作。我使用了 Container.ComposeExportedValue(client);在配置客户端实例后,在我的 mef 引导程序类中。现在模块的构造函数只需要一个客户端 :-) 谢谢!
猜你喜欢
  • 2011-05-09
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
  • 1970-01-01
  • 2017-04-28
相关资源
最近更新 更多