I'm trying to build an implementation of the IHttpControllerActivator
interface for with with StructureMap, so that I can resolve a dependency of a controller which takes a dependency on the HttpRequestMessage
being processed in the MVC Web API pipeline.
My implementation of Create
is as follows:
public IHttpController Create(
HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
return (IHttpController)this.Container
.With(request)
.With(controllerDescriptor)
.GetInstance(controllerType);
}
The Container
property is a reference to the StructureMap IContainer
instance passed to the activator when it is constructed.
My registration for the controllers uses reflection to obtain all the ApiController
implementations:
foreach(var controller in this.GetType().Assembly.GetTypes()
.Where(type => typeof(ApiController).IsAssignableFrom(type)))
{
this.For(controller).Use(controller);
}
Using the debugger, I checked that initialises the controller instances and passes in their dependencies. However, when the ExecuteAsync
method is called on the controller, an exception is thrown:
Cannot reuse an 'ApiController' instance. 'ApiController' has to be constructed per incoming message. Check your custom 'IHttpControllerActivator' and make sure that it will not manufacture the same instance.
After some digging and experimentation I discovered this is due to a check performed at the start of ExecuteAsync
which checks the Request
property of the ApiController
to see if it has been assigned a value. If the property has a non-null value, it infers that the controller has already been used to process a request and aborts the operation.
Further to this, I verified that StructureMap attempted to use its setter-injection behaviour when composing the controller and is responsible for Request
having a non-null value.
In my registry, I haven't configured any setter-injection, so I'm confused as to why it's being invoked here. A poke around the StructureMap API hasn't yielded any obvious answers as to how I could change the behaviour exhibited.
Am I invoking StructureMap incorrectly? Is there a configuration setting I can leverage to say "never ever assign a property value"?