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

2024-06-23

我正在使用 webapi、unity 和 mvc。我收到错误“确保控制器具有无参数公共构造函数”。我已经看到类似问题的解决方案,但仍然无法使其工作。我已经安装了 unity.webapi 并且似乎拥有所有必要的参考:

  • Microsoft.Practices.Unity - 运行时:v4.0.30319,版本:3.5.0.0
  • Microsoft.Practices.Unity.Mvc - 运行时:v4.0.30319,版本:3.5.0.0
  • Unity.WebApi - 运行时:v4.0.30319,版本:5.1.0.0
  • System.Web.Http - 运行时:v4.0.30319,版本:5.2.2.0
  • System.Web.Mvc - 运行时:v4.0.30319,版本:5.2.2.0

我验证了所有内容都与该网站上的内容相符:

http://www.asp.net/mvc/overview/releases/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-to-aspnet-mvc-5-and-web- API-2 http://www.asp.net/mvc/overview/releases/how-to-upgrade-an-aspnet-mvc-4-and-web-api-project-to-aspnet-mvc-5-and-web-api-2

这是我所拥有的:

引导程序:

public static class Bootstrapper
{
    public static IUnityContainer Initialise()
    {
        var container = BuildUnityContainer();

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
        return container;
    }

    private static IUnityContainer BuildUnityContainer()
    {
        var container = new UnityContainer();

        container.RegisterType<IDatabaseFactoryHouseDB, DatabaseFactoryHouseDB>(new HierarchicalLifetimeManager());
        container.RegisterType<UnitOfWorkHouseDB>();

        // repositories
        container.RegisterType<IEmployeeRepository, EmployeeRepository>();

        // services
        container.RegisterType<IEmployeeService, EmployeeService>();
        RegisterTypes(container);

        return container;
    }
    public static void RegisterTypes(IUnityContainer container) { }
}

全局.asax:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        Database.SetInitializer<HouseDBContext>(null);

        Bootstrapper.Initialise();
        //required for setting routes in the attributes of a controller method
        GlobalConfiguration.Configuration.EnsureInitialized();
    }
}

API控制器:

public class EmployeeApiController : ApiController
{
    private readonly IEmployeeService employeeService;

    public EmployeeApiController(IEmployeeService employeeService)
    {
        this.employeeService = employeeService;
    }

    // rest of controller
}

WebApi配置:

    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        // use json strings as the default return value for the app
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
        // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
        // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
        //config.EnableQuerySupport();

        // To disable tracing in your application, please comment out or remove the following line of code
        // For more information, refer to: http://www.asp.net/web-api
        config.EnableSystemDiagnosticsTracing();
    }

统一配置:

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();

        GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
    }
}

不知道我错过了什么。

Edit:我注意到我的 App_Start 文件夹中有一个 UnityConfig 类。在查看了 Sarathy 的评论后,我意识到它没有被调用。我在 global.asax 中注释掉了引导程序初始化,并添加了 UnityConfig.RegisterComponents() 行,所以现在我的 global.asax 看起来像这样:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        UnityConfig.RegisterComponents();  //  <--- added
        AreaRegistration.RegisterAllAreas();

        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        Database.SetInitializer<HouseDBContext>(null);

        //Bootstrapper.Initialise(); <-- not using bootstrapper anymore
        //required for setting routes in the attributes of a controller method
        GlobalConfiguration.Configuration.EnsureInitialized();
    }
}

我的 UnityConfig 如下所示:

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>();    
        container.RegisterType<IDatabaseFactoryHouseDB, DatabaseFactoryHouseDB>(new HierarchicalLifetimeManager());
        //container.RegisterType<IUnitOfWork>();
        container.RegisterType<UnitOfWorkHouseDB>();

        // repositories
        container.RegisterType<IEmployeeRepository, EmployeeRepository>();

        // services
        container.RegisterType<IEmployeeService, EmployeeService>();

        GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
    }
}

但我仍然收到无参数构造函数错误。有趣的是,即使我添加了一个无参数构造函数:

    public class EmployeeApiController : ApiController
    {
        private readonly IEmployeeService employeeService;

        public EmployeeApiController()
            : base()
        {
        } 

        public EmployeeApiController(IEmployeeService employeeService)
        {
            this.employeeService = employeeService;
        }
}

使用 unityconfig 方法时仍然出现错误。使用引导程序,我没有收到错误,但我的服务未初始化。

我完全困惑了。不知怎的,我觉得我正在混合 MVC 和 WebApi,但事情没有正确解决......

EDIT 2:

我查看了无参数构造函数错误的内部异常,并注意到它提到了我的 IUnitOfWork 类:

“依赖关系解析失败,类型 = \“AngularMVC.Controllers.EmployeeApiController\”,名称= \“(无)\”。\r\n异常发生时: 解析时。\r\n异常 是:InvalidOperationException -当前类型, AngularMVC.Models.Interfaces.IUnitOfWork,是一个接口,不能 被建造。您是否缺少类型 映射?\r\n-------------------------------------------------------- --\r\n在 异常发生时,容器为:\r\n\r\n 正在解决 AngularMVC.Controllers.EmployeeApiController,(无)\r\n 正在解析 构造函数的参数“employeeService” AngularMVC.Controllers.EmployeeApiController(AngularMVC.Services.IEmployeeService employeeService)\r\n 正在解决 AngularMVC.Services.EmployeeService,(none)(映射自 AngularMVC.Services.IEmployeeService,(无))\r\n 正在解析 构造函数的参数“unitOfWork” AngularMVC.Services.EmployeeService(AngularMVC.Models.Repositories.IEmployeeRepository 员工存储库,AngularMVC.Models.Interfaces.IUnitOfWork 工作单元)\r\n 正在解析 AngularMVC.Models.Interfaces.IUnitOfWork,(无)\r\n"

这只是这个:

public interface IUnitOfWork
{
    void Commit();
}

当我在 UnityConfig 中执行以下操作时:

        container.RegisterType<IUnitOfWork>();
        IUnitOfWork sm = container.Resolve<IUnitOfWork>();

我收到同样的错误,指出“当前类型 AngularMVC.Models.Interfaces.IUnitOfWork 是一个接口,无法构造。您是否缺少类型映射?”


从您的代码中,我可以看到您正在使用 Unity 作为 IoC 容器。 IoC容器将处理控制器类的初始化。

为了让 IoC 容器创建控制器的实例,控制器类需要有一个无参数的公共构造函数(也称为默认构造函数)。

public class EmployeeApiController : ApiController
{
    private readonly IEmployeeService employeeService;

    public EmployeeAPIController() : base()
    {
    }

    public EmployeeApiController(IEmployeeService employeeService)
    {
        this.employeeService = employeeService;
    }
}

更新 1:2015 年 2 月 18 日从您的代码中我没有看到 IUnitOfWork 接口的实现。工作单元是在领域中心建模中广泛使用的模式。通常,工作单元模式与存储库模式一起使用。工作单元的目的是使多个存储库可以在同一数据库上下文上工作。

通过您的代码,您可以注册

//container.RegisterType<IUnitOfWork>();
container.RegisterType<UnitOfWorkHouseDB>();

但是,我认为你应该有这样的注册代码:(我假设 UnitOfWorkHouseDB 是 IUnitOfWork 的实现)

container.RegisterType<IUnitOfWork, UnitOfWorkHouseDB>();

类似于:(EmployeeRepository是IEmployeeRepository的实现)

// repositories
container.RegisterType<IEmployeeRepository, EmployeeRepository>();

通常,当我使用工作单元和存储库模式时,我会执行以下结构:

IUnitOfWork 接口

public interface IUnitOfWork
{
    void Commit();
}

IUnitOfWork 实现:

public class UnitOfWork : IUnitOfWork
{
    //DBContext could your own db context, or a interface, like IDatabaseFactoryHouseDB 
    private DBContext _ctx;

    public UnitOfWork(DbContext ctx)
    {
        _ctx = ctx;
    }

    private IEmployeeRepository _EmployeeRepository;
    public IEmployeeRepository EmployeeRepository
    {
        get { return _EmployeeRepository ?? (_EmployeeRepository = new EmployeeRepository(_ctx)); }
    }

    private ICustomerRepository _CustomerRepository;
    public ICustomerRepository CustomerRepository
    {
        get { return _CustomerRepository ?? (_CustomerRepository = new CustomerRepository(_ctx)); }
    }

    public void Commit()
    {
        _ctx.SaveChange();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

错误:确保控制器具有无参数公共构造函数 webapi 的相关文章

随机推荐