代码之家  ›  专栏  ›  技术社区  ›  Dan Bryant

使用mef构建可扩展应用程序时的注意事项

  •  2
  • Dan Bryant  · 技术社区  · 14 年前

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

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

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

    我欢迎您对任何其他需要注意或令人惊讶的功能进行输入,这些功能已经改变了您的设计方式。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Wim Coenen    14 年前

    我有没有办法 限制我允许的特定导入 新实例化的扩展 决心?

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

    [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>();
    

    此代码不会引发组合异常。如果现在更改导入 我的扩展 去禁地 内部服务 ,您将得到所需的构图异常。

    这种设置的一个副作用是 公共服务 也不能导入任何私有服务,就像 我的扩展 . 这是有道理的,否则什么都不会停止 公共服务 通过属性公开私有服务。

    我已经用过 TypeCatalog 例如,但是在实践中,您可能应该使用 FilteredCatalog sample .

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

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

    如果这不能解决你的问题,看看 PartCreator sample 在mef源代码中(尽管注意它可能很快将被重命名为exportfactory,但它已经在mef的silverlight版本中)。