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

时间:2015-07-01 15:17:36

标签: c# import mef

我遇到以下问题:

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

由于我已经拥有一个现有实例(通过在下面的代码中创建一个实例进行模拟,并将其作为组合批处理的一部分添加),我只想在ServiceHost实例的Services属性中使用此实例。 (当然,其他类型的实例具有相同的接口实现..)

但是MEF总是也会创建一个新实例并将其推送到Services属性,这样就有两个实例 - 我自己创建的实例和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; }
    }
}

谢谢.. 伯尼

1 个答案:

答案 0 :(得分:1)

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

您必须做出决定:让MEF管理您的实例,或者自己动手。

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

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

在这种情况下,您手动将实例添加到compositionBatch,而DirectoryCatalog无法找到它,因为类没有[Exported]属性。