在MEF2中创建Singleton实例

时间:2018-08-29 19:40:55

标签: .net-core singleton composition mef2

我正在使用MEF2(Microsoft.Composition)创建具有多个插件的应用程序。这些插件应导入一些公共对象,并且它们都应共享该对象的相同实例……这就是典型的Singleton。

但是,当我将此[Import] static void Main(string[] args) { ContainerConfiguration containerConfig = new ContainerConfiguration() .WithAssembly(Assembly.GetExecutingAssembly()) .WithAssembly(typeof(ICommonObject).Assembly); using (CompositionHost container = containerConfig.CreateContainer()) { _mainApp = container.GetExport<MainApp>(); _mainApp.Start(); } } 插入我的插件时,它们都得到了自己的副本,而不是共享的副本。

在.NET Framework MEF1中,默认情况下所有对象都创建为单例。 .NET Core MEF2似乎并非如此。

如何确保我的所有插件都获得我的公共对象的相同单例实例?

示例代码

启动

[Export(typeof(MainApp))]
public class MainApp {
    [Import] public ICommonObject CommonObject { get; set; }
    [ImportMany] public IEnumerable<IPlugin> Plugins { get; set; }

    public void Start() {
        CommonObject.SomeValue = "foo";
        Console.WriteLine("SomeValue (from MainApp): " + CommonObject.SomeValue);

        foreach (IPlugin plugin in Plugins) {
            plugin.Start();
        }
    }
}

MainApp

[Export(typeof(IPlugin))]
public class SomePlugin : IPlugin {

    [Import] public ICommonObject CommonObject { get; set; }

    public void Start() {
        Console.WriteLine("SomeValue (from plugin): " + CommonObject.SomeValue);
    }
}

插件

SomeValue (from MainApp): foo
SomeValue (from plugin):

输出

{{1}}

1 个答案:

答案 0 :(得分:1)

经过反复尝试,我似乎终于找到了解决方法。

技巧似乎是使用ConventionBuilder。它具有一个名为.Shared()的扩展方法,该方法可使从特定类型派生的所有对象成为Singleton。

对于我的代码示例,只需将以下内容添加到启动代码的顶部:

ConventionBuilder conventions = new ConventionBuilder();
conventions.ForTypesDerivedFrom<ICommonObject>()
    .Export<ICommonObject>()
    .Shared();

ContainerConfiguration containerConfig = new ContainerConfiguration()
    .WithAssembly(Assembly.GetExecutingAssembly(), conventions);

由于某种原因,实现ICommonObject的对象甚至不需要[Export]属性。无论如何,该示例的输出现在为:

SomeValue (from MainApp): foo
SomeValue (from plugin): foo