确保控制器具有无参数的公共构造函数错误

我一直遵循这个 教程已经工作得很好,直到我修改了我的 DbContext有一个额外的构造函数。我现在有问题的决议,不知道该怎么办才能解决这个问题。是否有一种简单的方法可以强制它获取无参数构造函数,或者我没有正确地处理这个问题?

DbContext包含两个构造函数:

public class DashboardDbContext : DbContext
{
public DashboardDbContext() : base("DefaultConnection") { }


public DashboardDbContext(DbConnection dbConnection, bool owns)
: base(dbConnection, owns) { }
}

SiteController constructor:

private readonly IDashboardRepository _repo;


public SiteController(IDashboardRepository repo)
{
_repo = repo;
}

储存库:

DashboardDbContext _context;


public DashboardRepository(DashboardDbContext context)
{
_context = context;
}

UnityResolver代码:

public class UnityResolver : IDependencyResolver
{
private readonly IUnityContainer _container;


public UnityResolver(IUnityContainer container)
{
_container = container;
}


public object GetService(Type serviceType)
{
try
{
return _container.Resolve(serviceType);
}
catch (ResolutionFailedException)
{
return null;
}
}


public IEnumerable<object> GetServices(Type serviceType)
{
try
{
return _container.ResolveAll(serviceType);
}
catch (ResolutionFailedException)
{
return new List<object>();
}
}


public IDependencyScope BeginScope()
{
var child = _container.CreateChildContainer();
return new UnityResolver(child);
}


public void Dispose()
{
_container.Dispose();
}
}

WebApiConfig:

var container = new UnityContainer();
container.RegisterType<IDashboardRepository, DashboardRepository>(new HierarchicalLifetimeManager());
config.DependencyResolver = new UnityResolver(container);

来自 WebApi 调用的错误:

系统。InvalidOperationException: 试图创建类型为“ SiteController”的控制器时发生错误。确保控制器具有无参数的公共构造函数。

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.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()

输入“ Dashboard. Web.Controllers. siteController”没有缺省构造函数。

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)

The tutorial was great and has been working well for me up until I added the second constructor.

242752 次浏览

你被 这个问题咬了。基本上,发生的情况是您没有在容器中显式注册控制器。Unity 尝试为您解析未注册的具体类型,但是由于它不能解析它(由配置中的错误引起) ,所以它返回 null。它被迫返回 null,因为由于 IDependencyResolver契约,Web API 强制它这样做。因为 Unity 返回 null,所以 Web API 会尝试创建控制器本身,但是因为它没有缺省构造函数,它会抛出“确保控制器有一个无参数的公共构造函数”异常。此异常消息具有误导性,并且没有解释真正的原因。

You would have seen a much clearer exception message if you registered your controllers explicitly, and that's why you should always register all root types explicitly.

但是,当然,配置错误来自于将第二个构造函数添加到 DbContext。Unity 总是试图选择参数最多的构造函数,但是它不知道如何解析这个特定的构造函数。

因此,真正的原因是,您正在尝试使用 Unity 的自动布线功能来创建 DbContextDbContext是一种特殊类型,不应该自动接线。这是一个框架类型,你应该 因此回退到使用工厂委托注册它:

container.Register<DashboardDbContext>(
new InjectionFactory(c => new DashboardDbContext()));

In my case, it was because of exception inside the constructor of my injected dependency (in your example - inside DashboardRepository constructor). The exception was caught somewhere inside MVC infrastructure. I found this after I added logs in relevant places.

有时候因为你在用 containerbootstraper.cs 解析你的界面,所以很难发现错误。在我的例子中,在解析我注入到 api 控制器的接口的实现时出现了一个错误。我无法找到错误,因为我已经解析了 bootstraper 容器中的接口,如下所示: container.RegisterType<IInterfaceApi, MyInterfaceImplementaionHelper>(new ContainerControlledLifetimeManager());
然后在引导容器中添加以下代码行: container.RegisterType<MyController>(); 因此,当我编译的项目,编译器抱怨,停止在上面的行,并显示了错误。

我也有同样的问题,我通过修改 UnityConfig.cs 文件解决了这个问题。为了解决 UnityConfig.cs 文件中的依赖性问题,你必须添加:

public static void RegisterComponents()
{
var container = new UnityContainer();
container.RegisterType<ITestService, TestService>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

我也有同样的问题。我谷歌了两天。最后我意外地注意到问题是 Controller 构造函数的访问修饰符。 我没有把 public关键字放在 Controller 的构造函数后面。

public class MyController : ApiController
{
private readonly IMyClass _myClass;


public MyController(IMyClass myClass)
{
_myClass = myClass;
}
}

我把这次经历作为另一个答案,也许其他人也犯了类似的错误。

如果控制器中有接口

public myController(IXInterface Xinstance){}

你必须把它们登记在依赖注入上。

container.Bind<IXInterface>().To<XClass>().InRequestScope();

当我不小心将一个属性定义为一个特定的对象类型,而不是 UnityContainer 中定义的接口类型时,就会出现这个错误。

例如:

定义 UnityContainer:

var container = new UnityContainer();
container.RegisterInstance(typeof(IDashboardRepository), DashboardRepository);
config.DependencyResolver = new UnityResolver(container);

SiteController (错误的方式——注意回购类型) :

private readonly DashboardRepository _repo;


public SiteController(DashboardRepository repo)
{
_repo = repo;
}

SiteController (正确的方法) :

private readonly IDashboardRepository _repo;


public SiteController(IDashboardRepository repo)
{
_repo = repo;
}

如果您使用 UnityConfig.cs来抵抗类型的映射,如下所示。

public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IProductRepository, ProductRepository>();
}

您必须让 **webApiConfig.cs**了解容器

config.DependencyResolver = new Unity.AspNet.WebApi.UnityDependencyResolver(UnityConfig.Container);

In my case, Unity turned out to be a red herring. My problem was a result of different projects targeting different versions of .NET. Unity was set up right and everything was registered with the container correctly. Everything compiled fine. But the type was in a class library, and the class library was set to target .NET Framework 4.0. The WebApi project using Unity was set to target .NET Framework 4.5. Changing the class library to also target 4.5 fixed the problem for me.

我是通过注释掉 DI 构造函数并添加缺省构造函数来发现这一点的。我注释掉了控制器方法,并让它们抛出 NotExecmentedException。我确认我可以到达控制器,并且看到我的 NotExecmentedException 告诉我它正在很好地实例化控制器。接下来,在缺省构造函数中,我手动实例化了依赖链,而不是依赖 Unity。它仍然在编译,但是当我运行它时,错误消息返回。这对我来说证实了我仍然得到了错误,即使当联合是出了图片。最后,我从链的底部开始,逐步向上,一次注释一行,然后重新测试,直到不再收到错误消息。这为我指明了违规类的方向,从那里我发现它被隔离为一个单独的程序集。

我希望这个答案可以帮助别人避免浪费一天半的时间在这些东西上,例如 Nregister、 MVC 设计模式、 Global.asax、 Web Common 文件等等。

在我的情况下,这个错误本身完全是误导。

我的整个应用程序是工作的声音,除了当我调用一个特定的控制器,让调用 TestController

测试控制器使用 Njet 注入一个接口,让我们像这样调用 ITest

public class TestController : ApiController
{
private readonly ITest _test;


public TestController (ITest test)
{
_test= test;
}

我正在向 TestController中的一个方法发出一个简单的 GET 请求,并且正在为这个线程问题获得前面提到的错误。

我最终将其归结为只有当 ITest作为参数注入时才会出现的错误(因为我测试了一个不同的接口,它工作得很好!)

这导致我检查 Test类,并意识到我已经注入了一个 itself的实例到它!像这样

public class Test: ITest
{
private readonly ITest_test;


public Test(ITest test)
{
_test = test;
}

因此导致整个调用作为一个未处理的异常崩溃,并返回一个完全奇怪的错误,这对我毫无帮助!

安装 Nuget Package Unit. WebAP 而不是 Unity.MVC5确保使用 Nuget 安装了正确的 Unity 包

我安装了 Unity.MVC5并且遇到了类似的异常“无参数构造函数”

 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>();
container.RegisterType<ICar, Tesla>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}