简体   繁体   中英

MEF 2 SatisfyImportsOnce does not work on derived types

I'm struggling to understand why my code is working just when I replace the ImportProperty line with the implementor of the interface instead of the interface itself:

[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);
    }

The:

registrationBuilder.ForType().ImportProperty(flyweight => flyweight.Abstractions)

works fine but:

registrationBuilder.ForTypesDerivedFrom>>().ImportProperty(flyweight => flyweight.Abstractions)

doesn't although I believe they should be equivalent in my case.

I realized the "import" works only on classes and not on interfaces.

A solution could be importing all the properties:

registrationBuilder.ForTypesDerivedFrom<IImportingInterface>().ImportProperties(_ => true);

or

registrationBuilder.ForTypesDerivedFrom<IImportingInterface>().ImportProperties<ExportClass>(_ => true);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM