System.InvalidOperationException 设置构造函数注入时

System.InvalidOperationException when setting up constructor injection

我正在尝试使用 Ninject:

注入构造函数参数
    private void AddBindings()
    {
        //_kernel.Bind<IRestClient>().ToConstructor(x => new RestClient("http://localhost:49780/api/ProductApi"));
        _kernel.Bind<IRestClient>().ToConstructor(x => new RestClient(ConfigurationManager.AppSettings["ProductsApiUrl"]));
    }

但是我得到以下 System.InvalidOperationException

Operation is not valid due to the current state of the object.

当我改用注释掉的行时它工作正常。 我在调试模式下检查过 ConfigurationManager.AppSettings["ProductsApiUrl"] 等于 "http://localhost:49780/api/ProductApi".

为什么抛出这个异常?

这是 StackTrace:

   at System.Reflection.RuntimeMethodInfo.GetGenericMethodDefinition()
   at Ninject.Planning.Bindings.BindingBuilder.AddConstructorArgument(Expression argument, String argumentName, ParameterExpression constructorArgumentSyntaxParameterExpression)
   at Ninject.Planning.Bindings.BindingBuilder.AddConstructorArguments(NewExpression ctorExpression, ParameterExpression constructorArgumentSyntaxParameterExpression)
   at Ninject.Planning.Bindings.BindingBuilder.InternalToConstructor[TImplementation](Expression`1 newExpression)
   at Ninject.Planning.Bindings.BindingBuilder`1.ToConstructor[TImplementation](Expression`1 newExpression)
   at ShoppingCart.Infrastructure.NinjectDependencyResolver.AddBindings() in C:\Users\user1\Documents\ShoppingCart\ShoppingCart\Infrastructure\NinjectDependencyResolver.cs:line 35
   at ShoppingCart.Infrastructure.NinjectDependencyResolver..ctor(IKernel kernelParam) in C:\Users\user1\Documents\ShoppingCart\ShoppingCart\Infrastructure\NinjectDependencyResolver.cs:line 20
   at ShoppingCart.App_Start.NinjectWebCommon.RegisterServices(IKernel kernel) in C:\Users\user1\Documents\ShoppingCart\ShoppingCart\App_Start\NinjectWebCommon.cs:line 56
   at ShoppingCart.App_Start.NinjectWebCommon.CreateKernel() in C:\Users\user1\Documents\ShoppingCart\ShoppingCart\App_Start\NinjectWebCommon.cs:line 46
   at Ninject.Web.Common.Bootstrapper.Initialize(Func`1 createKernelCallback)
   at ShoppingCart.App_Start.NinjectWebCommon.Start() in C:\Users\user1\Documents\ShoppingCart\ShoppingCart\App_Start\NinjectWebCommon.cs:line 25

编辑:

我刚刚意识到如果我这样做就可以正常工作:

    string productsApiUrl = ConfigurationManager.AppSettings["ProductsApiUrl"];
    _kernel.Bind<IRestClient>().ToConstructor(x => new RestClient(productsApiUrl));

为什么评估 ConfigurationManager.AppSettings["ProductsApiUrl"] 很重要?

我在 GitHub 上看过 AddConstructorArgument()。 它有以下 if 语句:

if (!(argument is MethodCallExpression methodCall) ||
                !methodCall.Method.IsGenericMethod ||
                methodCall.Method.GetGenericMethodDefinition().DeclaringType != typeof(IConstructorArgumentSyntax))

它正在调用 GetGenericMethodDefinition() 的事实意味着 !methodCall.Method.IsGenericMethodfalse,即。 IsGenericMethod returns true.

然而,根据 MSDN InvalidOperationException 只有在 IsGenericMethod returns false 时才会抛出。

所以我对 InvalidOperationException 的抛出方式感到困惑。

很明显旧版本有bug。使用 Resharper 反编译时,我可以看到没有 IsGenericMethod 检查,只有:

  if (methodCallExpression != null && !(methodCallExpression.Method.GetGenericMethodDefinition().DeclaringType != typeof (IConstructorArgumentSyntax)))
    return;

那么 GetGenericMethodDefinition() 会失败,因为你的表达式 - ConfigurationManager.AppSettings["ProductsApiUrl"] 不是通用的。