Question

I want to register and resolve dynamically loaded types based on their class attribute. My code is as follows:

The custom class attribute:

[MetadataAttribute]
public class FooIdentifier : Attribute
{
    public string Identifier { get; private set; }

    public FooIdentifier(string identifier)
    {
        this.Identifier = identifier;
    }
}

My abstract base class

public abstract class Base
{
    public abstract bool Execute(object param);

    public bool Run(object param = null)
    {
        //...
        return true;
    }
}

My implementation types

[FooIdentifier("230")]
public class Child1 : Base
{
    public override bool Execute(object param)
    {
        throw new NotImplementedException();
    }
}

[FooIdentifier("250")]
public class Child2 : Base
{
    public override bool Execute(object param)
    {
        throw new NotImplementedException();
    }
}

I do not want to have a hard reference so i will load the assembly manually. My goal is to resolve the concrete implementation based on the Identifier of the class attribute. I have tried a lot with metadata, metadatafrom, keyed etc etc. My current try is:

        var builder = new ContainerBuilder();
        var assembly = Assembly.LoadFrom(@"[PathToAssembly].dll");

        builder.RegisterModule<AttributedMetadataModule>();

        builder.RegisterAssemblyTypes(assembly)
            .Where(t => t.IsSubclassOf(typeof(Base)))
            //.As<Base>() or .AsImplementedInterfaces()
            .WithMetadataFrom<TaskIdentifier>();

        var container = builder.Build();
        var child = test.ResolveKeyed<Base>("230"); // here i want to have child1

Can someone help me with this?

Was it helpful?

Solution

 builder.RegisterAssemblyTypes(assembly)
        .Where(t => t.IsSubclassOf(typeof(Base)) &&
                    t.GetCustomAttribute<FooIdentifier>() != null)
        .Keyed<Base>(t => t.GetCustomAttribute<FooIdentifier>().Identifier);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top