I am using the
Dependency Resolver which is instantiating my ApiController but immediatly after instantiating the ApiController it throws an exception.
I'm assuming this exception is because the Mechanism that invokes the correct action in my controller is failing for some reason. I have no idea what to do because there is no way for me to get the MVC4 source code and step through the problem.
Here is the exception message that gets thrown immediately after my ApiController is instantiated using a Dependency Resolver.
Exception Type: System.ArgumentException
Exception Message: Method T Resolve[T]() is a generic method definition
Stack Trace:
at System.Linq.Expressions.Expression.ValidateMethodInfo(MethodInfo method) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable'1 arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.GetExecutor(MethodInfo
methodInfo) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.set_MethodInfo(MethodInfo value) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor..ctor(HttpControllerDescriptor controllerDescriptor, MethodInfo methodInfo) at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.<.ctor>b__4(MethodInfo
method) at System.Array.ConvertAll[TInput,TOutput](TInput[] array, Converter'2 converter) at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem..ctor(HttpControllerDescriptor controllerDescriptor) at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext
controllerContext) at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken
cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
When I call /api/States i get the error message. Here is my StatesController which is an ApiController
public class StatesController : ApiControllerBase {
// GET /api/states
public IEnumerable<StateEntity> Get()
{
IStatesService service = Resolve<IStatesService>();
return service.GetAllStates();
}
}
My ApiController Base looks like this:
public class ApiControllerBase : ApiController
{
[Dependency]
public DIContainer DIContainer {get;set;}
public T Resolve<T>()
{
if (this.DIContainer == null) throw new Exception("DIContainer not initialized!");
return this.DIContainer.Resolve<T>();
}
}
My Global.asax code I register the Service Resolver like so:
protected void Application_Start()
{
// ... code for registering routes and global filters are the mvc template defaults
// I added these next 2 lines
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new UnityApiControllerResolver());
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());
}
Here is the code for my UnityApiControllerResolver.cs
public class UnityApiControllerResolver : IDependencyResolver
{
public object GetService(Type serviceType)
{
try { return DIBuilder.Create().Resolve(serviceType); }
catch (ResolutionFailedException) { return null; }
}
public IEnumerable<object> GetServices(Type serviceType)
{
try { return DIBuilder.Create().ResolveAll(serviceType); }
catch (ResolutionFailedException) { return new List<object>(); }
}
}
DIBuilder.Create() returns my Unity Container.
Stepping thru the code, I can see that the ApiController (StatesController) gets instantiated but the Action "Get()" never gets invoked..
Is there a reason you are using Dependency Injection this way? I would use the built-in dependency resolution, you can access the resolver in your actions via base.Configuration.ServiceResolver. Also, I would consider using Constructor Injection for these
dependencies..
If you need to keep this design, then make sure your Resolve<T> method is protected or slap on the [NonActionAttribute] on the method.
Dave
Dave Bettin
@dbettin
Marked as answer by evan.larsen on Mar 07, 2012 06:09 PM
evan.larsen
Member
20 Points
23 Posts
Web Api Dependency Resolver works but Action Invoker isn't..
Mar 07, 2012 04:30 PM|LINK
I am using the Dependency Resolver which is instantiating my ApiController but immediatly after instantiating the ApiController it throws an exception.
I'm assuming this exception is because the Mechanism that invokes the correct action in my controller is failing for some reason. I have no idea what to do because there is no way for me to get the MVC4 source code and step through the problem.
Here is the exception message that gets thrown immediately after my ApiController is instantiated using a Dependency Resolver.
Exception Type: System.ArgumentException
Exception Message: Method T Resolve[T]() is a generic method definition
Stack Trace:
at System.Linq.Expressions.Expression.ValidateMethodInfo(MethodInfo method) at System.Linq.Expressions.Expression.Call(Expression instance, MethodInfo method, IEnumerable'1 arguments) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.GetExecutor(MethodInfo methodInfo) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.set_MethodInfo(MethodInfo value) at System.Web.Http.Controllers.ReflectedHttpActionDescriptor..ctor(HttpControllerDescriptor controllerDescriptor, MethodInfo methodInfo) at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.<.ctor>b__4(MethodInfo method) at System.Array.ConvertAll[TInput,TOutput](TInput[] array, Converter'2 converter) at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem..ctor(HttpControllerDescriptor controllerDescriptor) at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext) at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncInternal(HttpRequestMessage request, CancellationToken cancellationToken) at System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
Any Ideas?
davebettin
Member
313 Points
94 Posts
Re: Web Api Dependency Resolver works but Action Invoker isn't..
Mar 07, 2012 04:41 PM|LINK
What do your actions look like in your ApiController?
@dbettin
Arch4ngel
Member
175 Points
31 Posts
ASPInsiders
MVP
Re: Web Api Dependency Resolver works but Action Invoker isn't..
Mar 07, 2012 05:17 PM|LINK
Could you show us some basic code?
How is your controller defined (with attributes)? How did you setup the dependency resolver?
You don't need to show us company code but at least something for us to work with.
Cheers,
evan.larsen
Member
20 Points
23 Posts
Re: Web Api Dependency Resolver works but Action Invoker isn't..
Mar 07, 2012 05:46 PM|LINK
When I call /api/States i get the error message. Here is my StatesController which is an ApiController
public class StatesController : ApiControllerBase {
// GET /api/states
public IEnumerable<StateEntity> Get()
{
IStatesService service = Resolve<IStatesService>();
return service.GetAllStates();
}
}
My ApiController Base looks like this:
public class ApiControllerBase : ApiController
{
[Dependency]
public DIContainer DIContainer {get;set;}
public T Resolve<T>()
{
if (this.DIContainer == null) throw new Exception("DIContainer not initialized!");
return this.DIContainer.Resolve<T>();
}
}
My Global.asax code I register the Service Resolver like so:
protected void Application_Start()
{
// ... code for registering routes and global filters are the mvc template defaults
// I added these next 2 lines
GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new UnityApiControllerResolver());
ControllerBuilder.Current.SetControllerFactory(new UnityControllerFactory());
}
Here is the code for my UnityApiControllerResolver.cs
public class UnityApiControllerResolver : IDependencyResolver
{
public object GetService(Type serviceType)
{
try { return DIBuilder.Create().Resolve(serviceType); }
catch (ResolutionFailedException) { return null; }
}
public IEnumerable<object> GetServices(Type serviceType)
{
try { return DIBuilder.Create().ResolveAll(serviceType); }
catch (ResolutionFailedException) { return new List<object>(); }
}
}
DIBuilder.Create() returns my Unity Container.
Stepping thru the code, I can see that the ApiController (StatesController) gets instantiated but the Action "Get()" never gets invoked..
davebettin
Member
313 Points
94 Posts
Re: Web Api Dependency Resolver works but Action Invoker isn't..
Mar 07, 2012 05:58 PM|LINK
A couple of comments:
Is there a reason you are using Dependency Injection this way? I would use the built-in dependency resolution, you can access the resolver in your actions via base.Configuration.ServiceResolver. Also, I would consider using Constructor Injection for these dependencies..
If you need to keep this design, then make sure your Resolve<T> method is protected or slap on the [NonActionAttribute] on the method.
Dave
@dbettin