1
votes

I posted an issue on SM repo.

My question is similar to this one, but I'd like to localize a problem.

Let's say I have generic interface IPrinter<T> and its generic implementation Printer<T>. I'd like StructureMap to resolve the concrete closed type Printer<string> when I do container.GetInstance<IPrinter<string>>.

Explicit registration works OK here:

container.Configure(r => r.For(typeof (IPrinter<>)).Use(typeof (Printer<>)));

But the scan stuff fails: RegisterConcreteTypesAgainstTheFirstInterface() results in 202 No Default Instance defined StructureMap exception when I'm trying to resolve IPrinter<string>.

Is there a way to accomplish the behavior I want without explicit configuration?

1

1 Answers

1
votes

ConnectImplementationsToTypeClosing() works just fine but you have to know how it works. It registers types with Add() method which is quite different in its behavior than registrations done with Use() method. Detailed explanation can be found here. In short when you get 202 error code that does not mean you have not registered any concrete types for requested plugin type. It could be the case that you have registered them more than one and no default instance is specified.

Hope this helps.

EDIT

By this: "It could be the case that you have registered them more than one and no default instance is specified" I meant that more than one implementations of the same plugin type was registered, e.g. for

IPrinter<string>

you have defined:

StringPrinter1 : IPrinter<string> and StringPrinter2 : IPrinter<string>

Not that you are allowed to register only one type for IPrinter<>.

When you want to register multiple implementations of the same generic plugin type, e.g.

IPrinter<string>

then I advise to use:

var container = new Container(c => c.Scan(s => s.AddAllTypesOf(typeof(IHandler<>)).NameBy(t => t.Name)));

to have named registrations and then resolve them by name explicitly:

var stringPrinter1 = container.GetInstance<IPrinter<string>>("StringPrinter1");

or by using such registration:

c.For<IMyTypeUsingPrinter>().Use<MyTypeUsingPrinter>().Ctor<IPrinter<string>>().Named("StringPrinter1");

them MyTypeUsingPrinter would have injected StringPrinter1 as IPrinter< string > dependency.