zcz527 / autofac

Automatically exported from code.google.com/p/autofac
Other
0 stars 0 forks source link

ExtensibleActionInvoker incorrectly resolves Uri[] parameters #324

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Use InjectionActionInvoker() and ExtensibleActionInvoker from Mvc Integration
2. Create a controller action with a parameter of type Uri[]
3. Create a view page with list of checkboxes for parameter
4. Submit page to controller

What is the expected output? What do you see instead?
We expect to see the parameter containing the list of Uri's posted by the page. 
Instead, the parameter is always an empty array.

What version of Autofac are you using? On what version of .NET/Silverlight?
AutoFac 2.2.4.900, .NET 4.0, MVC 3.0

I've tracked it down to the following lines in ExtensibleActionInvoker :
if (this._context.IsRegistered(parameterDescriptor.ParameterType))
{
  return this._context.Resolve(parameterDescriptor.ParameterType);
}

For some reason the context contains a registration for Uri[], despite me never 
having added one. Therefore this binds to Uri[], and returns an empty array.

Original issue reported on code.google.com by sean.hed...@gmail.com on 6 May 2011 at 6:34

GoogleCodeExporter commented 8 years ago
G'day - thanks for the report.

In the most recent Autofac MVC integration (2.4.x) the parameter injection 
behaviour is switched off by default, which will fix this problem. We disabled 
the feature because of this kind of scenario - Autofac can always resolve 
arrays of items (an empty array just means no components with that service have 
been registered) but of course in this case the outcome is unpredictable.

If you are using parameter injection elsewhere in your MVC app I'd suggest 
subclassing ExtensibleActionInvoker to alter the behavior.

Hope this helps,
Nick

Original comment by nicholas...@gmail.com on 8 May 2011 at 6:10

GoogleCodeExporter commented 8 years ago
Ah cool. I'd already done that as a workaround. What I did was:

protected override object GetParameterValue(ControllerContext 
controllerContext, ParameterDescriptor parameterDescriptor)
{
    var result = base.GetParameterValue(controllerContext, parameterDescriptor);
    if (result == null && this._context.IsRegistered(parameterDescriptor.ParameterType))
        result = this._context.Resolve(parameterDescriptor.ParameterType);
    return result;
}

So, it only tries to resolve the parameter if it can't be found by the base 
invoker. In other words, it's only injected if not passed in. Wouldn't this be 
an acceptable default behaviour?

Original comment by sean.hed...@gmail.com on 8 May 2011 at 7:10