尝试创建类型的控制器时发生错误。确保控制器具有无参数的公共构造函数

时间:2018-08-21 10:46:59

标签: c# asp.net-mvc asp.net-web-api dependency-injection autofac

我已将依赖项注入与代码优先实体框架集成在一起。但是当我那个时候调用api方法时,我得到了错误。

  

System.InvalidOperationException:尝试创建类型为'DrugController'的控制器时发生错误。确保控制器具有无参数的公共构造函数。

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:

  

System.ArgumentException:类型'SA_Admin.Controllers.DrugController'没有默认的构造函数

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)

但是当我删除带有参数的构造函数时,我可以调用而不会出错。

我交叉检查了每个文件,但没有出错。我缺少什么?另外,由于控制器没有构造函数,所以所有帐户方法都可以正常工作。

项目仅是Web api项目。我没有添加mvc。

我使用了Autofac DI nuget程序包。

建议我解决方案。

Startup.cs

    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        ConfigureOAuth(app);

        WebApiConfig.Register(config);
        app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
        app.UseWebApi(config);

        IoCConfig.RegisterDependencies();
    }

IOCConfig.cs

public class IoCConfig
{
    /// <summary>
    /// For more info see
    /// :http://docs.autofac.org/en/latest/integration/mvc.html
    /// </summary>
    public static void RegisterDependencies()
    {
        #region Create the builder 
        var builder = new ContainerBuilder();
        #endregion

        #region Register all authentication dependencies
        // REGISTER DEPENDENCIES
        builder.RegisterType<SA_AdminEntities>().AsSelf().InstancePerRequest(); 
        #endregion   

        #region Register all web api controllers for the assembly
        builder.RegisterApiControllers(typeof(Startup).Assembly);
        #endregion

        #region Register modules
        builder.RegisterModule(new BusinessLogicInstaller());
        builder.RegisterModule(new ReposInstaller());
        builder.RegisterModule(new ServicesInstaller());
        #endregion 

        #region Set the dependency resolver to be Autofac
        var container = builder.Build(); 
        //for WebApi
        GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
        #endregion
    }
}

ServiceInstaller.cs

public class ServicesInstaller : Module
{
    protected override void Load(ContainerBuilder builder)
    { 
        builder.RegisterAssemblyTypes(typeof(DrugService).Assembly)
            .Where(t => t.Name.EndsWith("Service"))
            .AsImplementedInterfaces()
            .InstancePerRequest();
    }
}

RepoInstaller.cs

public class ReposInstaller : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
        builder.RegisterType<DbFactory>().As<IDbFactory>().InstancePerRequest();

        #region Repositories 
        builder.RegisterAssemblyTypes(typeof(DrugRepo).Assembly)
            .Where(t => t.Name.EndsWith("Repo"))
            .AsImplementedInterfaces().InstancePerRequest();
        #endregion  
    }

}

BusinessLogicInstaller.cs

public class BusinessLogicInstaller : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterType<ParamEncryption>().As<IParamEncryption>().InstancePerRequest();
        builder.RegisterType<Mapper>().As<IMapper>().InstancePerRequest(); 
    }
}

WebApiConfig.cs

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.Filters.Add(new ErrorLogApiHandler());

        var constraintResolver = new DefaultInlineConstraintResolver
        {
            ConstraintMap = { ["apiVersion"] = typeof(ApiVersionRouteConstraint) }
        };
        //removes xml formatter
        config.Formatters.Remove(config.Formatters.XmlFormatter);

        //enable json formatters
        config.Formatters.JsonFormatter.SerializerSettings.ContractResolver =
            new CamelCasePropertyNamesContractResolver();

        //TODO Turn off move to dev and prod
        //enable cors
        //config.EnableCors(new EnableCorsAttribute("*", "*", "*"));
        //add api versioning 
        ApiVersion apiVersion = new ApiVersion(1, 0);
        config.AddApiVersioning(options =>
        {
            //will return the headers "api-supported-versions" and "api-deprecated-versions"
            options.ReportApiVersions = true;

            //TODO define api controllers here with versions
            //Like below Example
            options.Conventions.Controller<DrugController>().HasApiVersion(apiVersion);

        });

        //enable attribute routing
        config.MapHttpAttributeRoutes(constraintResolver);
    }
}

ApiController

[ApiVersion("1.0")]
[RoutePrefix("api/v{version:apiVersion}/Public")]
public class DrugController : ApiController
{
    #region Variables
    private readonly IDrugService drugService;

    private readonly IPersistService persistService;        
    private readonly IParamEncryption encryptor;
    #endregion

    #region Constructor

    public DrugController(IDrugService drugService, IPersistService persistService, IParamEncryption encryptor)
    {
        this.drugService = drugService; 
        this.persistService = persistService; 
        this.encryptor = encryptor;
    }

    [Route("Drugs")]
    [HttpGet]
    public IHttpActionResult Drugs()
    {
        HttpResponseMessage resp;
        try
        {
            var lstdrugs = drugService.GetDrugs(xx => true);
            resp = Request.CreateResponse(HttpStatusCode.OK, lstdrugs);
        }
        catch (Exception ex)
        {
            resp = Request.CustomHandleError(ex);
        }

        return ResponseMessage(resp);
    }
    #endregion
}

2 个答案:

答案 0 :(得分:2)

如果未在autofac容器中注册参数之一,则会遇到相同的错误。实际错误可能是内部异常的多层下降。我只看到注册了IParamEncryption。注册其他两个接口。

答案 1 :(得分:0)

查看此链接可解决您的问题,主要是DI注册和解析器问题。

有关更多信息,请参见以下帖子。

https://stackoverflow.com/a/24257085/7404931