views:

44

answers:

1

i have 2 concrete types "CategoryFilter" & "StopWordsFilter" that implements "IWordTokensFilter".

Below is my setup:

ForRequestedType<IWordTokensFilter>().TheDefaultIsConcreteType<CategoryFilter>()
            .AddInstances(x =>
            {
                x.OfConcreteType<StopWordsFilter>();
            }
        );

The problem is the run-time when structure map auto inject it on my class, bec. i have arguments with same plugin-type:

public ClassA(IWordTokensFilter stopWordsFilter, IWordTokensFilter categoryFilter)

i'm always getting CategoryFilter in my first argument but it should be stopWordsFilter.

How can i setup this in a right way? thanks in advance

+1  A: 

There are a number of possible solutions:

1) Does ClassA need to differentiate between the filters, or does it just need to run them both? If not, you can change the constructor to accept an array, which will cause all registered instances of IWordTokensFilter to be injected:

public ClassA(IWordTokensFilter[] filters)

You can then foreach over the filters to apply them.

2) If you do need to differentiate them, because they need to be used differently, you may consider having one implement a marker interface the better describes its purpose. ClassA could then be changed to take in an IWordTokensFilter and an ICategoryFilter (or whatever you name the marker interface). Register CategoryFilter with ICategoryFilter and then both will be injected properly.

public ClassA(IWordTokensFilter stopWordsFilter, ICategoryFilter categoryFilter)

3) You can tell StructureMap explicitly how to create ClassA:

ForRequestedType<ClassA>().TheDefault.Is.ConstructedBy(c => {
  return new ClassA(c.GetInstance<StopWordsFilter>(), c.GetInstance<CategoryFilter>());
});

4) You can tell StructureMap to override one of the dependencies for ClassA:

x.ForRequestedType<ClassA>().TheDefault.Is.OfConcreteType<ClassA>()
  .CtorDependency<IWordTokensFilter>("stopWordsFilter").Is<StopWordsFilter>();
Joshua Flanagan
Hi Joshua, i'm really satisfied with your answers. I would like to choose solution 1 but i have a lot of filters. So, i decided to use 3 or 4. Btw, will structuremap auto-inject all concrete types to an array arguments in your solution 1?.. Many thanks again.
happy
Yes, it will auto-inject all concrete instances it knows about. You can tell it about instances explicitly using AddInstances (as in your example), or call AddAllTypesOf within a Scan.
Joshua Flanagan
Thanks again Dude.
happy