问题
我使用Unity作为IoC,这很好,但是随着我不断添加功能,发现任何错误变得越来越困难,因为团结提供了一个错误,它是错误的症状,而不是实际错误:
"Message":"An error has occurred.","ExceptionMessage":"An error occurred
when trying to create a controller of type 'MyController'. Make sure that the
controller has a parameterless public
constructor.","ExceptionType":"System.InvalidOperationException"
背景
我有一个MVC Web Api控制器,它依赖Manager实例(来自域):
public class MyController : ApiController
{
private IMyManager MyManager { get; set; }
public MyController(IMyManager myManager)
{
this.MyManager = myManager;
}
...
}
发生上述错误是因为IoC映射IMyManager失败。当它失败时,我没有参数,这意味着MyController是使用无参数构造函数调用的,但是由于它不存在(而且不应该),所以我得到了上面的错误。
我已经尝试过的
所以,我得到的错误不是“真正的”错误。显而易见的是要确保每个新的实现都在IoC下注册,我检查了它们。我手动做这件事是为了保持事情的可管理性(噢,讽刺!)
我就是这样做的:
container.RegisterType<IMyManager, MyManager>();
但是,这不是问题所在。
我做的一个解决办法是循环依赖。我将所有涉及的构造函数和方法更改为使用属性值,而不是实例。我检查了所有涉及的类,不再存在任何循环依赖关系。
然而,问题仍然存在。
问题
我怎样才能找出实际的问题呢?手动检查依赖关系的开销太大,因为该结构是一个复杂的更深层次依赖关系的网络。随着应用程序的成熟,情况会变得更糟。
或者,如果联合总是掩盖这些消息(而无法修复),那么是否有其他方法确实提供了有价值的错误信息?
更新
对于每个请求,完整的错误消息(虽然我不认为堆栈跟踪非常有用):
{"Message":"An error has occurred.","ExceptionMessage":"An error occurred when trying to create a controller of type 'MyController'. Make sure that the controller has a parameterless public constructor.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Type 'MyProject.Web.Api.Controllers.MyController' does not have a default constructor","ExceptionType":"System.ArgumentException","StackTrace":" at System.Linq.Expressions.Expression.New(Type type)
at System.Web.Http.Internal.TypeActivator.Create[TBase](Type instanceType)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.GetInstanceOrActivator(HttpRequestMessage request, Type controllerType, Func`1& activator)
at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)"}}
更新2
我进行了更深入的研究,检查了所有的依赖项(它们非常庞大),但是所有的东西都被正确地注册和加载。也没有任何循环依赖,所以据我所能告诉‘应该’工作。因为这不是我的结论,有一些错误发生了,但没有被抛出。
发布于 2015-10-15 15:09:50
我发现了它,问题是我正在以相同的解决方案重新编译现有的代码,这意味着会有相同名称的重复文件。
在这个特定的例子中,我有一个与以前存在的接口完全相同的接口。在代码的某个地方,我使用了错误的命名空间,这意味着IoC映射是不正确的。
所以,就像这样:
我有:
old.managers.IMyManager
和
new.managers.IMyManager
我在地图上所做的是:
container.RegisterType<IMyManager, MyManager>();
在本例中,IMyManager是new.managers.IMyManager,这是应该的。
这种依赖关系的使用者之一期望命名空间的IMyManager (名称空间old.managers )。
更新使用者以使用新的命名空间修复它。
发布于 2015-10-14 10:34:02
如果错误说您需要一个无参数的构造函数,那么这就意味着WebAPI没有注册,即使它是为您的ASP.NET MVC应用程序注册的。如果您的IoC工作正常,它不应该需要一个无参数的构造函数,因为它应该能够解决控制器构造函数中存在的依赖关系。
WebAPI有自己的通往ASP.NET MVC的管道--例如,WebAPI可以托管在own上,因此即使它们存在于同一个项目中,也需要单独连接。
您应该将WebAPI连接到UnityConfig中的依赖项解析器,我相信这里有一个示例:http://www.devtrends.co.uk/blog/using-unity.mvc5-and-unity.webapi-together-in-a-project
using Microsoft.Practices.Unity;
using System.Web.Http;
using System.Web.Mvc;
namespace WebApplication1
{
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// register all your components with the container here
// it is NOT necessary to register your controllers
// e.g. container.RegisterType<ITestService, TestService>();
// Configures container for ASP.NET MVC
DependencyResolver.SetResolver(new Unity.Mvc5.UnityDependencyResolver(container));
// Configures container for WebAPI
GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
}
}
}
在上面的示例中,有两行用于配置,但它们共享相同的容器,因此也共享相同的绑定--您不必对它们进行两次定义。如果您曾经将WebAPI项目与ASP.NET MVC项目分开,那么您就必须有一个单独的容器和绑定。
根据我的经验,在发现问题,或者对您隐藏错误的统一方面,情况并非如此。您所遇到的错误直接来自ASP.NET MVC。在没有IoC的正常使用中,您需要一个无参数的构造函数.使用IoC,它控制控制器的创建,从而解决依赖关系。
发布于 2020-11-27 15:05:24
别忘了这一点在你的web.config
<system.web>
<compilation targetFramework="4.8" />
<httpRuntime targetFramework="4.8" />
<customErrors mode="Off" />
</system.web>
缺少httpRuntime targetFramework="4.8“部分将导致无参数公共构造函数错误
https://stackoverflow.com/questions/33122410
复制相似问题