【问题标题】:Considerations when architecting an extensible application using MEF使用 MEF 构建可扩展应用程序时的注意事项
【发布时间】:2023-03-11 02:12:01
【问题描述】:

我已经开始为我的一个项目尝试依赖注入(特别是 MEF),该项目有许多不同的可扩展点。我开始了解我可以用 MEF 做什么,但我想听听其他对这项技术有更多经验的人的意见。几个具体案例:

  1. 目前我的主要用例是公开我的扩展使用的各种类似单例的服务。我的框架程序集公开了服务接口,我的引擎程序集包含了具体的实现。这很好用,但我可能不想让我的所有扩展都可以访问我的所有服务。 MEF 中是否有一种好方法可以限制我允许新实例化的扩展解析哪些特定导入?

  2. 这个特定的应用程序有我反复实例化的扩展对象。我可以导入多种类型的控制器和机器,它们以不同的组合实例化为一个项目。我找不到使用 MEF 执行此操作的好方法,所以我正在做自己的类型发现和实例化。有没有在 MEF 或其他 DI 框架中执行此操作的好方法?

我欢迎您就任何其他需要注意的事项或您发现的改变了您的架构方式的令人惊讶的功能提供意见。

【问题讨论】:

  • 另外 stackoverflow.com/questions/293051/… 考虑使用 StructureMap、Ninject、CastleWindsor 或 Autofac。
  • 感谢您的链接;他们很有帮助。我已经更新了我的问题的标题,以更好地阐明我所追求的。 MEF 似乎很适合我的要求,因为可扩展性是我追求的主要目标。我对 IoC 还不是很了解;你认为它更适合我提到的案例吗?
  • MEF 是一个扩展框架,因此它有利于事后的扩展。由于 IOC 有点简单,我建议从它开始。 1. 我不确定是否有任何 IOC 可以按照您描述的方式限制对服务的访问。 2. IOC 可以更好地控制对象的实例化方式。您可以在每次请求对象获取不同版本时传递参数。我不确定 MEF 是否会处理这个问题,因为我认为 MEF 只加载一次扩展。
  • 老实说,我确实觉得 MEF 有点怪异。我添加了一些属性,调用 Compose,然后整个对象层次结构突然出现,并带有神奇出现的引用。这让我感觉就像是拿着一把魔豆的杰克。肯定还有很多值得探索的地方。

标签: wpf architecture dependency-injection mef


【解决方案1】:

在 MEF 中是否有一个好方法可以 限制我允许的特定进口 一个新实例化的扩展 解决了吗?

将扩展代码加载到单独的容器中,并确保该容器中没有受限部分。让我们将情况简化为这些类来构造一个示例:

[Export]
public class MyExtension
{
   [Import]
   public PublicService Service { get; set; }

}

[Export]
public class PublicService
{
}

[Export]
public class InternalService
{
}

[Export]
public class Program
{
   [Import]
   public MyExtension Extension { get; set; }

   [Import]
   public PublicService Service1 { get; set; }

   [Import]
   public InternalService Service2 { get; set; }
}

目标是允许MyExtension 导入PublicService,但不允许 InternalService。像Program 这样的内部代码应该可以导入任何东西。你可以这样实现:

var publicCatalog = new TypeCatalog(typeof(PublicService), typeof(MyExtension));
var publicContainer = new CompositionContainer(publicCatalog);

var internalCatalog = new TypeCatalog(typeof(Program), typeof(InternalService));
var internalContainer = 
    new CompositionContainer(internalCatalog, publicContainer);

var program = internalContainer.GetExport<Program>();

此代码不会引发合成异常。如果您现在将MyExtension 上的导入更改为禁止的InternalService,您将获得所需的合成异常。

这种设置的副作用是PublicService 也不能导入任何私人服务,就像MyExtension。这是有道理的,因为否则没有什么能阻止PublicService 通过属性公开私有服务。

我以TypeCatalog 为例,但实际上您可能应该使用FilteredCatalog sample 之类的东西。

这个特定的应用程序有 我反复的扩展对象 实例化。我可以导入多个 控制器和机器的类型, 以不同的方式实例化 项目的组合。我不能 找到一个使用 MEF 的好方法, 所以我正在做自己的类型发现和 实例化。有没有什么好办法 在 MEF 或其他 DI 中执行此操作 框架?

您可能只是在 PartCreationPolicy 属性之后,该属性控制部件是共享的(如,每个容器仅创建一次)还是每次导入时多次实例化。您还可以在导入属性中指定RequiredCreationPolicy 参数。

如果这不能解决您的问题,请查看 MEF 源代码中的 PartCreator sample(但请注意,它可能很快会重命名为 ExportFactory,它已经在 MEF 的 Silverlight 版本中了)。

【讨论】:

  • 谢谢,这很有帮助。我得再读一些关于目录的书。
猜你喜欢
  • 2012-02-19
  • 2014-07-06
  • 2016-02-23
  • 2010-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
相关资源
最近更新 更多