使用 ImportMany 和可组合部件的现有实例进行 MEF 组合

MEF composition using ImportMany and existing instances of composable parts

我遇到了以下问题:

在 MEF 上使用 ImportMany 属性时,MEF 始终至少会创建一个 IService 接口实现的实例。

因为我已经有一个现有的实例(通过在下面的代码中创建一个并将其作为合成批处理的一部分添加来模拟),我只想在我的服务中拥有这个实例 属性 ServiceHost 实例的。 (当然还有来自具有相同接口实现的其他类型的实例..)

但是 MEF 总是也会创建一个新实例,并将其推送到服务 属性,这样就有两个实例 - 我自己创建的一个和 MEF 创建的一个。

如何防止 MEF 创建自己的实例?

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;

namespace TestConsole
{
    public interface IService
    {
        int InstanceId { get; }
    }

    public class Program
    {
        public static int counter;

        private static void Main(string[] args)
        {
            ServiceHost host = new ServiceHost();

            DirectoryCatalog catalog = new DirectoryCatalog(".", "*.exe");
            CompositionContainer container = new CompositionContainer(catalog);
            CompositionBatch compositionBatch = new CompositionBatch();

            // create an existing instance
            TestService c = new TestService();
            ComposablePart part = AttributedModelServices.CreatePart(c);
            compositionBatch.AddPart(part);
            Console.WriteLine("existing instance: {0}", c.InstanceId);

            compositionBatch.AddPart(AttributedModelServices.CreatePart(host));

            container.Compose(compositionBatch);

            foreach (var service in host.Services)
            {
                Console.WriteLine(service.InstanceId);
            }
        }
    }

    public class ServiceHost
    {
        [ImportMany]
        public IService[] Services { get; set; }
    }

    [Export(typeof(IService))]
    public class TestService : IService
    {
        public TestService()
        {
            this.InstanceId = ++Program.counter;
        }

        public int InstanceId { get; private set; }
    }
}

谢谢.. 伯尼

所以它按预期工作。它找到 2 个实例,因为您添加了两个实例(一个手动添加,一个来自 DirectoryCatalog)。

您必须做出决定:让 MEF 管理您的实例,还是您自己管理。

如果可能,删除 [Export(typeof(IService))] 并使用 AddExportedValue 代替部分,如下所示:

// create an existing instance
TestService c = new TestService();
compositionBatch.AddExportedValue<IService>(c);

在这种情况下,您手动将实例添加到 compositionBatch,而 DirectoryCatalog 找不到它,原因是 class 没有 [Exported] 属性。