.net core 在MEF2中创建单例实例

.net core 在MEF2中创建单例实例,.net-core,singleton,composition,mef2,.net Core,Singleton,Composition,Mef2,我正在使用MEF2(Microsoft.Composition)创建一个包含多个插件的应用程序。这些插件应该导入一些公共对象,它们应该共享这个对象的相同实例。。。所以是典型的单身汉 然而,当我将这个公共对象导入我的插件时,它们都会得到自己的副本,而不是共享的副本 在.NET Framework MEF1中,默认情况下,所有对象都创建为单例。对于.NET核心MEF2,情况似乎并非如此 如何确保我的所有插件都获得相同的公共对象的单例实例 示例代码 启动 输出 经过反复试验,我似乎终于自己找到了解决办

我正在使用MEF2(Microsoft.Composition)创建一个包含多个插件的应用程序。这些插件应该导入一些公共对象,它们应该共享这个对象的相同实例。。。所以是典型的单身汉

然而,当我将这个公共对象导入我的插件时,它们都会得到自己的副本,而不是共享的副本

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

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

示例代码 启动 输出
经过反复试验,我似乎终于自己找到了解决办法

诀窍似乎是使用
ConventionBuilder
。这有一个名为
.Shared()
的扩展方法,它将从特定类型派生的所有对象都转换为一个单例

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

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

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

有没有一种方法可以通过属性实现这一点?
[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();
        }
    }
}
[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):
ConventionBuilder conventions = new ConventionBuilder();
conventions.ForTypesDerivedFrom<ICommonObject>()
    .Export<ICommonObject>()
    .Shared();

ContainerConfiguration containerConfig = new ContainerConfiguration()
    .WithAssembly(Assembly.GetExecutingAssembly(), conventions);
SomeValue (from MainApp): foo
SomeValue (from plugin): foo