views:

79

answers:

1

I am using structure map and setting up a service based on the profile string passed. I have a list of objects. List of IProcessors that I need to inject to the RecognizerSaga to process against each of these processors.

Say, bootstrapping code looks something like this:

x.CreateProfile("A1", p => {
        p.Type<IProcessor>().Is.OfConcreteType<TestAProcessor>();
        p.Type<IProcessor>().Is.OfConcreteType<TestBProcessor>();
        p.Type<IProcessor>().Is.OfConcreteType<TestCProcessor>();
    }

x.CreateProfile("B2", p => {
        p.Type<IProcessor>().Is.OfConcreteType<TestAProcessor>();
        p.Type<IProcessor>().Is.OfConcreteType<TestBProcessor>();
    });

When I get these processors I try to build it using ObjectFactory.GetAllInstances<IProductProcessor> and it returns me all 5 of them though I have setup the default profile as A1. Is there a way to get all instances within a profile. If I say, A1, get me only 3 of them?

For work around I build a factory class which builds object for me, but I would prefer having structuremap all the way.

A: 

Sadly this is not currently possible in StructureMap.

The idea of a profiles is to specify the default concrete type for a plugin type. Each time you configure the profile default type for the same interface you redefine the default concrete type.

Another way to do what you are looking for would be to configure an array of types to be passed a concrete type which itself is set as the default type for a profile.

Here is an example with tests proving it works:

    public interface IProcessor { }
public class ProcessorA : IProcessor { }
public class ProcessorB : IProcessor { }
public class ProcessorC : IProcessor { }

public class ProcessorGroup
{
    public IProcessor[] Processors { get; private set; }

    public ProcessorGroup(IProcessor[] processors)
    {
        Processors = processors;
    }
}

public class ProcessorRegistry : Registry
{
    public ProcessorRegistry()
    {
        CreateProfile("a", profile =>
        {
            profile.For<ProcessorGroup>().UseNamedInstance("a");
        });

        CreateProfile("b", profile =>
        {
            profile.For<ProcessorGroup>().UseNamedInstance("b");
        });

        ForConcreteType<ProcessorGroup>()
            .Configure.WithName("a")
            .TheArrayOf<IProcessor>().Contains(a =>
            {
                a.OfConcreteType<ProcessorA>();
            });

        ForConcreteType<ProcessorGroup>()
            .Configure.WithName("b")
            .TheArrayOf<IProcessor>().Contains(a =>
            {
                a.OfConcreteType<ProcessorB>();
                a.OfConcreteType<ProcessorC>();
            });
    }
}

[TestFixture]
public class test
{
    [Test]
    public void processor_group_a()
    {
        var container = new Container(new ProcessorRegistry());

        container.SetDefaultsToProfile("a");
        var processorGroup = container.GetInstance<ProcessorGroup>();

        processorGroup.Processors.Length.ShouldEqual(1);
    }   

    [Test]
    public void processor_group_b()
    {
        var container = new Container(new ProcessorRegistry());

        container.SetDefaultsToProfile("b");
        var processorGroup = container.GetInstance<ProcessorGroup>();

        processorGroup.Processors.Length.ShouldEqual(2);
    }   
}
KevM