Nicolas Cadilhac
Nicolas Cadilhac

Reputation: 4745

How to set a default constructor argument to null with StructureMap?

A class has a unique constructor taking IMyInterface as its argument. If I define a concrete type of IMyInterface and registers it to StructureMap then there is no issue and my class can be instanciated with this concrete type.

However, in some cases, no concrete type will be registered. In that case, I would like to receive null for the IMyInterface parameter. Instead I get an exception:

StructureMap Exception Code: 202 No Default Instance defined for PluginFamily IMyInterface.

Is it possible to define a default value for a missing plugin?

Context: my class, which is a service, uses the Spark view engine and defines some default namespaces. The service uses a ISparkNamespacesProvider (IMyInterface) to add aditional namespaces. The client app may register such a provider or not. That's why the constructor of the service will receive either a provider or none.

Upvotes: 2

Views: 2233

Answers (2)

Malcolm
Malcolm

Reputation: 1259

StructureMap now supports this case via UseIfNone https://structuremap.github.io/registration/fallback-services/

Upvotes: 0

Arnis Lapsa
Arnis Lapsa

Reputation: 47577

Taken from here:

For<IService>().Use<MyService>()
 .Ctor<IMyInterface>("nameOfParameter").Is(null);

But You should think about why Your class is dependent on IMyInterface. If it's optional - that's a code smell. Maybe You should refactor it out as method argument for method that needs it or as settable property.

There shouldn't be need for switching between concrete implementation and null. When composing dependency graph at composition root, You should know exactly what will be Your dependencies w/o .If(isSomething()).Use<MyService>().Ctor<IMyInterface>(null).

You might want to check out this tekpub presentation and this book (look for so called MEAP access) about DI and IOC.


One way to accomplish what You want is using so called 'poor man dependency injection'. That is - to define second constructor:

public MyClass():this(null){...}

But I wouldn't recommend that.

Upvotes: 2

Related Questions