我正在切换到.net核心并尝试将我的旧框架MEF代码迁移到新的Microsoft Composition (MEF 2)(Microsoft.Composition 1.0.31)。
我们有几个类,其创建政策是" NonShared"。我不知道如何使用带有.net核心的MEF 2来应用以下属性:
[PartCreationPolicy(CreationPolicy.NonShared)]
有没有人知道.net核心MEF 2相当于将上述属性设置为' NonShared'?
答案 0 :(得分:5)
由于只有MEF 2被移植到.NET Core,我们只能访问 System.Composition 中的类型,而不能访问 System.ComponentModel.Composition 中的类型。因此,无法像以前那样使用MEF 1设置该属性。
您可以为通过API定义的每个导出设置部件创建策略。
因为我们在万圣节附近,所以我们有这些课程:
abstract class Monster { }
class It : Monster { }
class Zombie : Monster { }
class Wife : Monster { }
在MEF 2中,您需要创建一个ConventionBuilder来阻止您的导出,如下所示:
var rules = new ConventionBuilder();
rules.ForTypesDerivedFrom<Monster>()
.Export<Monster>();
这里有趣的部分是默认情况下强制执行非共享创建策略,因此不需要该属性。我们来测试一下:
var config = new ContainerConfiguration()
.WithAssemblies(new[]{ typeof(Monster).GetTypeInfo().Assembly}, rules);
var container = config.CreateContainer();
var monsterA = container.GetExports<Monster>().First();
var monsterB = container.GetExports<Monster>().First();
Console.WriteLine(monsterA == monsterB);
现在,由于默认情况下我们不会在导出中强制执行共享,因此会写入控制台 False 。
为了加强分享,我们只需在 .Export 之后将 .Shared()添加到方法链中:
rules.ForTypesDerivedFrom<Monster>()
.Export<Monster>()
.Shared();
如果我们再次运行测试,我们将获得 True ,因为现在两个实例都指向相同的引用。
对于编写零件,您可以这样做:
class TerrorContainer
{
[ImportMany]
public IEnumerable<Monster> Monsters { get; set; }
}
无论你在哪里写作,你都会写:
var terrorContainer = new TerrorContainer();
container.SatisfyImports(terrorContainer);
希望这有帮助!