Политика создания МЭФ - PullRequest
2 голосов
/ 05 мая 2009

Я пытаюсь использовать политику создания разделяемой части для экспорта 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 ]

3 голосов
/ 05 мая 2009

Я не вижу в вашем коде ничего такого, что могло бы привести к созданию более одной вашей части. Вы создаете разные контейнеры для каждой композиции? Если да, вот почему вы получаете отдельные экземпляры.

Что касается того, как комбинировать композицию и модульное тестирование в целом, здесь есть некоторое обсуждение этого здесь .

2 голосов
/ 15 мая 2009

Что я сделал для модульного тестирования, так это избегал композиции. Например (здесь я использую WPF и MVVM), допустим, вы хотите протестировать эту ViewModel:

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

    private ILoggingService logger { get; set; }

    /* ... */
}

Я не хочу создавать полноценную службу ведения журналов каждый раз, когда выполняю модульный тест, поэтому у меня есть класс MockLoggingService, который реализует ILoggingService и просто проглатывает все сообщения журнала (или проверяет, что правильные сообщения генерируется, если вы заботитесь). Тогда я могу сделать это в моем модульном тесте:

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