MEF创建政策

时间:2009-05-05 03:36:14

标签: c# mef

我正在尝试将共享部件创建策略用于MEF导出。然而,它似乎并没有像我想的那样工作。我在我的应用程序中执行两次合成,每次都获得该对象的新副本。我通过向对象实例添加实例计数器

来证明这一点
    static int instCount = 0;

    public FakeAutocompleteRepository()
    {
        instCount++;
        ...
    }

并在调试中运行它。确实,第二次我做了一个合成,我得到了一个新的FakeAutocompleteRepository副本,其中instCount = 2.导出部分包含

[PartCreationPolicy(CreationPolicy.Shared)]
[Export(typeof(IAutocompleteRepository))]
[ExportMetadata("IsTesting", "True")]
class FakeAutocompleteRepository : IAutocompleteRepository
{ ... }

为次要请求获取相同的实例是否有一些技巧?如果它是我在作曲中做的事情,那就是我在做那个

var catalog = new AggregateCatalog();
                catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()));
                catalog.Catalogs.Add(new DirectoryCatalog("."));
                var container = new CompositionContainer(catalog);
                var batch = new CompositionBatch();
                batch.AddPart(this);
                container.Compose(batch);


                if (null != ConfigurationSettings.AppSettings["IsTesting"] && bool.Parse(ConfigurationSettings.AppSettings["IsTesting"]))
                    repository = container.GetExports<IAutocompleteRepository>().Where(expDef => expDef.Metadata.Keys.Contains("IsTesting")).Single().GetExportedObject();

基本上我试图在测试期间强制使用特定的组合物。如果您对单元测试这些成分有更好的想法,那么我就是全部的耳朵。

2 个答案:

答案 0 :(得分:3)

我没有在您的代码中看到任何特定内容会导致您创建多个部分。您是否为每种构图创建了不同的容器?如果你是,那就是你获得单独实例的原因。

关于如何将组合和单元测试结合起来,对此here进行了一些讨论。

答案 1 :(得分:2)

我为单元测试所做的是避免构图。例如(我在这里使用WPF和MVVM),假设你想测试这个ViewModel:

[Export("/MyViewModel")]
public class MyViewModel
{
    [ImportingConstructor]
    public MyViewModel(
        [Import("/Services/LoggingService")] ILoggingService l)
    {
        logger = l;
    }

    private ILoggingService logger { get; set; }

    /* ... */
}

我不希望每次进行单元测试时都实例化完整的日志服务,所以我有一个实现ILoggingService的MockLoggingService类,它只是吞下所有日志消息,(或检查正确的消息是正在生成,如果你关心)。然后我可以在我的单元测试中做到这一点:

MyViewModel target = new MyViewModel(new MockLoggingService());