我正在尝试使用Simple Injector做一些基本的构造函数DI,看来它无法解决Web API控制器的依赖关系。
SimpleInjectorWebApiDependencyResolver
这似乎不是问题,但是我仍然收到以下错误:
类型’MyProject.API.ArticleController’没有默认的构造函数 System.ArgumentException在 System.Web.Http.Internal.TypeActivator.System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage请求,类型controllerType的System.Web.Http.Internal.TypeActivator.Create [TBase](Type instanceType)的System.Linq.Expressions.Expression.New(Type type) ,Func`1&activator)在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage请求,HttpControllerDescriptor controllerDescriptor,类型controllerType)
类型’MyProject.API.ArticleController’没有默认的构造函数
System.ArgumentException在
System.Web.Http.Internal.TypeActivator.System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage请求,类型controllerType的System.Web.Http.Internal.TypeActivator.Create [TBase](Type instanceType)的System.Linq.Expressions.Expression.New(Type type) ,Func`1&activator)在System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage请求,HttpControllerDescriptor controllerDescriptor,类型controllerType)
如果有人可以向我提供一些建议,关于是否应从其当前状态/呼叫顺序进行任何修改,将不胜感激。
ArticleController(基本结构):
public class ArticleController : ApiController { private readonly IArticleRepository articleRepository; private readonly IUserRepository userRepository; private readonly IReleaseRepository releaseRepository; public ArticleController(IArticleRepository articleRepository, IUserRepository userRepository, IReleaseRepository releaseRepository) { this.articleRepository = articleRepository; this.userRepository = userRepository; this.releaseRepository = releaseRepository; } // GET api/Article public IEnumerable<Article> GetArticles(){ // code } // GET api/Article/5 public Article GetArticle(int id){ // code } // PUT api/Article/5 public HttpResponseMessage PutArticle(int id, Article article){ // code } // POST api/Article public HttpResponseMessage PostArticle(ArticleModel article){ // code } // DELETE api/Article/5 public HttpResponseMessage DeleteArticle(int id){ // code } }
SimpleInjectorInitializer:
public static class SimpleInjectorInitializer { public static void Initialize() { var container = new Container(); InitializeContainer(container); container.RegisterMvcControllers(Assembly.GetExecutingAssembly()); container.RegisterMvcAttributeFilterProvider(); container.Verify(); DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container)); } private static void InitializeContainer(Container container) { container.Register<IArticleRepository, ArticleRepository>(); container.Register<IUserRepository, UserRepository>(); container.Register<IReleaseRepository, ReleaseRepository>(); } }
Global.asax.cs:
public class WebApiApplication : System.Web.HttpApplication { private void ConfigureApi() { // Create the container as usual. var container = new Container(); // Verify the container configuration // container.Verify(); // Register the dependency resolver. GlobalConfiguration.Configuration.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container); } protected void Application_Start() { AreaRegistration.RegisterAllAreas(); ConfigureApi(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } }
TLTR: 问题是由Web API处理解析控制器类型的隐式方式引起的;显式注册您的Web API控制器,您将看到问题出在哪里。
这是逐步进行的幕后工作:
System.Web.Http.DefaultHttpControllerActivator
SimpleInjector.Container
Container
IServiceProvider.GetService
GetService
null
DependencyResolver
DefaultHttpControllerActivator
简而言之,问题是由Web API处理解析控制器类型的隐式方式引起的。
因此,这里的解决方案是:
container.Verify()
我的建议是将MVC和Web API放在自己的项目中。这将使事情变得容易得多。
可以使用以下代码注册所有Web API控制器:
container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
更新:
由于此错误非常普遍,因此在请求控制器类型时,SimpleInjectorWebApiDependencyResolver该类的较新版本将 永远不会 返回null。相反,它将引发一个描述性错误。因此,只要您使用Official,就永远不会再看到错误SimpleInjectorWebApiDependencyResolver。