首页 文章

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

提问于
浏览
86

我已经按照这个tutorial进行了很好的工作,直到我修改了 DbContext 以获得额外的构造函数 . 我现在遇到了解决方案的问题,不知道如何解决这个问题 . 是否有一种简单的方法可以强制它 grab 无参数构造函数,或者我接近这个错误?

DbContext 有两个构造函数:

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

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

SiteController 构造函数:

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调用出错:

System.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()

InnerException:System.ArgumentException:Type'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)

该教程非常棒,并且在我添加第二个构造函数之前一直很好用 .

7 回答

  • 0

    我有同样的问题,我通过在UnityConfig.cs文件中进行更改来解决它为了解决UnityConfig.cs文件中的依赖性问题,您必须添加:

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

    什么's happening is that you'被this problem咬了 . 基本上,发生的事情是你没有解决它(由你的配置中的错误引起),它返回null . 它被强制返回null,因为Web API强制它由于 IDependencyResolver Contract 而这样做 . 由于Unity返回null,Web API将尝试创建控制器本身,但因为它没有解释真正的原因 .

    如果您明确注册了控制器,您会看到更清晰的异常消息,这就是您应该始终明确注册所有根类型的原因 .

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

    因此,真正的原因是您正在尝试使用Unity的自动布线功能来创建 DbContext . DbContext 是一种不应自动连线的特殊类型 . 它是一种框架类型,您应该therefore fallback to registering it using a factory delegate

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

    在我的情况下,这是因为我注入的依赖项的构造函数内部的异常(在您的示例中 - 在DashboardRepository构造函数内) . 这个例外是在MVC基础设施内部捕获的 . 我在相关地方添加了日志后发现了这一点 .

  • 112

    有时因为你在ContainerBootstraper.cs中解析你的接口,所以's very difficult to catch the error. In my case there was an error in resolving the implementation of the interface I'已经注入了api控制器 . 我找不到错误,因为我已经解决了我的bootstraperContainer中的接口,如下所示: container.RegisterType<IInterfaceApi, MyInterfaceImplementaionHelper>(new ContainerControlledLifetimeManager());
    然后我在我的bootstrap容器中添加了以下行: container.RegisterType<MyController>(); 所以当我编译项目时,编译器抱怨并停在上面一行并显示错误 .

  • 4

    我有同样的问题 . 我用Google搜索了两天 . 最后我不小心注意到问题是Controller的构造函数的访问修饰符 . 我没有把 public 关键字放在Controller的构造函数后面 .

    public class MyController : ApiController
        {
            private readonly IMyClass _myClass;
    
            public MyController(IMyClass myClass)
            {
                _myClass = myClass;
            }
        }
    

    我将此经验添加为另一个答案,也许其他人犯了类似的错误 .

  • 1

    如果控制器中有接口

    public myController(IXInterface Xinstance){}
    

    您必须将它们注册到依赖注入容器 .

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

    当我不小心将属性定义为特定对象类型而不是我在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;
    }
    

相关问题