我试图用Simple Injector做一些基本的构造函数DI,似乎它无法解析Web API控制器的依赖关系。
SimpleInjectorWebApiDependencyResolver
,它与找到的here相同。这不是 似乎是一个问题,但我仍然收到以下错误:
类型'MyProject.API.ArticleController'没有默认值 构造
的System.ArgumentException
System.Linq.Expressions.Expression.New(Type type)at System.Web.Http.Internal.TypeActivator.Create [TBASE](类型 instanceType)at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage 请求,输入controllerType,Func`1&激活者) System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage 请求,HttpControllerDescriptor controllerDescriptor,Type 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);
}
}
答案 0 :(得分:42)
TLTR:问题是由Web API处理解析控制器类型的隐式方式引起的;明确注册您的Web API控制器,您将看到问题所在。
以下是幕后发生的一步一步:
System.Web.Http.DefaultHttpControllerActivator
调用SimpleInjectorWebApiDependencyResolver
并请求创建API控制器。SimpleInjectorWebApiDependencyResolver
将该调用转发给SimpleInjector.Container
个实例。Container
实例没有为该API控制器进行任何显式注册(因为您向解析器提供了一个空容器)。IServiceProvider.GetService
方法请求了类型,并且类型未明确注册。SimpleInjectorWebApiDependencyResolver
的{{1}}方法也会返回GetService
,因为根据定义,它应该返回null;如果不存在注册(当前就是这种情况),它应该返回null。null
返回null,DependencyResolver
将回退到其默认行为,这意味着自己创建该类型,但这需要控制器具有默认构造函数。长话短说,问题是由Web API处理解析控制器类型的隐式方式引起的。
所以这里的解决方案是:
DefaultHttpControllerActivator
。这可以防止各种麻烦和配置复杂化。Container
,这会在配置无效时启动应用程序失败(verifiable configuration is important)。这也允许您diagnose the configuration,这使您对配置的正确性更有信心。 我的advice is to place MVC and Web API in their own project。这将使事情变得更容易。
可以使用以下代码注册所有Web API控制器:
container.Verify()
<强>更新强>
由于此错误非常常见,因此在请求控制器类型时,container.RegisterWebApiControllers(GlobalConfiguration.Configuration);
类的较新版本只会从不返回SimpleInjectorWebApiDependencyResolver
。相反,它会引发描述性错误。因此,只要您使用官方null
。
答案 1 :(得分:0)
以下设置对我有用:
1)包含https://www.nuget.org/packages/Unity.WebAPI/中的 Unity.WebAPI 2)在 UnityConfig
中public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// **** Important note -----
// register all your components with the container here
// e.g. container.RegisterType<ITestService, TestService>();
DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
}
}
3)在 Global.asax 文件
中 public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
要开始使用,只需在Global.asax.cs的Application_Start方法中添加对UnityConfig.RegisterComponents()的调用 然后Web API框架将使用Unity.WebAPI DependencyResolver来解析您的组件。
例如
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
UnityConfig.RegisterComponents(); // <----- Add this line
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
在UnityConfig类的RegisterComponents方法中添加您的Unity注册。实现IDisposable的所有组件都应 向HierarchicalLifetimeManager注册,以确保在请求结束时正确处理它们。