MEF 2 SatisfyImportsOnce 不适用于派生类型
MEF 2 SatisfyImportsOnce does not work on derived types
我很难理解为什么当我用接口的实现者而不是接口本身替换 ImportProperty 行时我的代码能正常工作:
[TestFixture]
public class FlyweightTest
{
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
class FlyweightIntegerKeyAttribute : ExportAttribute, IFlyweightKey<int>
{
public int Key { get; private set; }
public FlyweightIntegerKeyAttribute(int key) : base(typeof(IAbstraction)) { Key = key; }
}
public interface IAbstraction { }
[FlyweightIntegerKey(1)]
class Abstraction1 : IAbstraction { }
[FlyweightIntegerKey(2)]
class Abstraction2 : IAbstraction { }
[Test]
public void Test()
{
IMefFlyweight<IAbstraction, IFlyweightKey<int>> lFlyweight = new Flyweight();
Initialize(lFlyweight);
Assert.AreEqual(2, lFlyweight.Abstractions.Count());
Assert.IsTrue(lFlyweight.Abstractions.Select(lazy => lazy.Value).OfType<Abstraction1>().Any());
Assert.IsTrue(lFlyweight.Abstractions.Select(lazy => lazy.Value).OfType<Abstraction2>().Any());
}
//public interface IMefFlyweight<T, TMetadata>
//{
// IEnumerable<Lazy<T, TMetadata>> Abstractions { get; set; }
//}
public class Flyweight : IMefFlyweight<IAbstraction, IFlyweightKey<int>>
{
public IEnumerable<Lazy<IAbstraction, IFlyweightKey<int>>> Abstractions { get; set; }
}
public void Initialize(IMefFlyweight<IAbstraction, IFlyweightKey<int>> @object)
{
var catalog = new AggregateCatalog();
var registrationBuilder = new RegistrationBuilder();
registrationBuilder.ForTypesDerivedFrom<IAbstraction>().Export<Lazy<IAbstraction, IFlyweightKey<int>>>();
//registrationBuilder.ForTypesDerivedFrom<IMefFlyweight<IAbstraction, IFlyweightKey<int>>>().ImportProperty(flyweight => flyweight.Abstractions);
// This one works:
registrationBuilder.ForType<Flyweight>().ImportProperty(flyweight => flyweight.Abstractions);
foreach (var lAssembly in AppDomain.CurrentDomain.GetAssemblies())
catalog.Catalogs.Add(new AssemblyCatalog(lAssembly, registrationBuilder));
var container = new CompositionContainer(catalog);
container.SatisfyImportsOnce(@object, registrationBuilder);
}
那个:
registrationBuilder.ForType().ImportProperty(flyweight => flyweight.Abstractions)
工作正常但是:
registrationBuilder.ForTypesDerivedFrom>>().ImportProperty(flyweight => flyweight.Abstractions)
虽然我认为它们在我的情况下应该是等效的。
我意识到 "import" 只适用于 类 而不是接口。
解决方案可能是导入所有属性:
registrationBuilder.ForTypesDerivedFrom<IImportingInterface>().ImportProperties(_ => true);
或
registrationBuilder.ForTypesDerivedFrom<IImportingInterface>().ImportProperties<ExportClass>(_ => true);
我很难理解为什么当我用接口的实现者而不是接口本身替换 ImportProperty 行时我的代码能正常工作:
[TestFixture]
public class FlyweightTest
{
[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
class FlyweightIntegerKeyAttribute : ExportAttribute, IFlyweightKey<int>
{
public int Key { get; private set; }
public FlyweightIntegerKeyAttribute(int key) : base(typeof(IAbstraction)) { Key = key; }
}
public interface IAbstraction { }
[FlyweightIntegerKey(1)]
class Abstraction1 : IAbstraction { }
[FlyweightIntegerKey(2)]
class Abstraction2 : IAbstraction { }
[Test]
public void Test()
{
IMefFlyweight<IAbstraction, IFlyweightKey<int>> lFlyweight = new Flyweight();
Initialize(lFlyweight);
Assert.AreEqual(2, lFlyweight.Abstractions.Count());
Assert.IsTrue(lFlyweight.Abstractions.Select(lazy => lazy.Value).OfType<Abstraction1>().Any());
Assert.IsTrue(lFlyweight.Abstractions.Select(lazy => lazy.Value).OfType<Abstraction2>().Any());
}
//public interface IMefFlyweight<T, TMetadata>
//{
// IEnumerable<Lazy<T, TMetadata>> Abstractions { get; set; }
//}
public class Flyweight : IMefFlyweight<IAbstraction, IFlyweightKey<int>>
{
public IEnumerable<Lazy<IAbstraction, IFlyweightKey<int>>> Abstractions { get; set; }
}
public void Initialize(IMefFlyweight<IAbstraction, IFlyweightKey<int>> @object)
{
var catalog = new AggregateCatalog();
var registrationBuilder = new RegistrationBuilder();
registrationBuilder.ForTypesDerivedFrom<IAbstraction>().Export<Lazy<IAbstraction, IFlyweightKey<int>>>();
//registrationBuilder.ForTypesDerivedFrom<IMefFlyweight<IAbstraction, IFlyweightKey<int>>>().ImportProperty(flyweight => flyweight.Abstractions);
// This one works:
registrationBuilder.ForType<Flyweight>().ImportProperty(flyweight => flyweight.Abstractions);
foreach (var lAssembly in AppDomain.CurrentDomain.GetAssemblies())
catalog.Catalogs.Add(new AssemblyCatalog(lAssembly, registrationBuilder));
var container = new CompositionContainer(catalog);
container.SatisfyImportsOnce(@object, registrationBuilder);
}
那个:
registrationBuilder.ForType().ImportProperty(flyweight => flyweight.Abstractions)
工作正常但是:
registrationBuilder.ForTypesDerivedFrom>>().ImportProperty(flyweight => flyweight.Abstractions)
虽然我认为它们在我的情况下应该是等效的。
我意识到 "import" 只适用于 类 而不是接口。
解决方案可能是导入所有属性:
registrationBuilder.ForTypesDerivedFrom<IImportingInterface>().ImportProperties(_ => true);
或
registrationBuilder.ForTypesDerivedFrom<IImportingInterface>().ImportProperties<ExportClass>(_ => true);