如何在web api中注入ihttprouteconstrint ?

本文关键字:注入 ihttprouteconstrint api web | 更新日期: 2023-09-27 17:51:13

正如标题所述,我需要能够将服务注入到web api约束类中。我正在使用SimpleInjector在我的c# webApi项目。

在我的webApiConfig.cs中我有这个

// add constraint resolvers
var constraintResolver = new DefaultInlineConstraintResolver();
constraintResolver.ConstraintMap.Add("dynamicName", typeof(DynamicRouteConstraint));
// routing
config.MapHttpAttributeRoutes(constraintResolver);

我的自定义约束看起来像这样

public class DynamicRouteConstraint : IHttpRouteConstraint
{
    private IDynamicRouteService _service;
    public DynamicRouteConstraint(IDynamicRouteService service)
    {
        _service = service;
    }
    public bool Match(System.Net.Http.HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
    {
        return _service.Match(values[parameterName].ToString());
    }
}

正如你所看到的,我需要注入iddynamicrouteservice到我的约束。目前我的应用程序抛出一个错误说

没有为这个对象定义无参数构造函数。

但是我不想要一个无参数的构造函数,因为我需要注入服务。

我已经将这行添加到我的SimpleInjectorConfig文件中,在这里我注册了所有的类来注入

container.RegisterWebApiRequest<IDynamicRouteService, DynamicRouteService>();

我已经创建了实现接口的实际服务,如下(精简版本)

public class DynamicRouteService : IDynamicRouteService
{
    private IModuleService _service;
    public DynamicRouteService(IModuleService service)
    {
        _service = service;
    }
    public ICollection<DynamicRouteModel> GetRoutes()
    {
        var list = new List<DynamicRouteModel>();
        // custom code usually here
        return list;
    }
    public void Clear()
    {
        // custom code usually here
    }
    public bool Match(string name)
    {
        // custom code usually here
        return false;
    }
}

我的IModuleService服务被注入没有任何问题,因为它工作得很好,我只需要能够注入iddynamicrouteservice到我的约束。

感谢您的帮助

编辑

这是我当前的SimpleInjector Register方法

public static Container Register(HttpConfiguration apiConfig)
{
    var container = new Container();
    container.RegisterPerWebRequest<HttpContextBase>(() => new HttpContextWrapper(HttpContext.Current));
    container.RegisterPerWebRequest<HttpConfiguration>(() => apiConfig);
    // EnableHttpRequest and IDynamicNameService are needed to get the name of the module
    // that is requested via the DynamicDataController
    container.EnableHttpRequestMessageTracking(apiConfig);
    container.RegisterWebApiRequest<IDynamicModuleService, DynamicRouteService>();
    // service for dynamicRoute checking
    container.Register<IDynamicRouteService, DynamicRouteService>();
    // This is an extension method from the integration package.
    container.RegisterWebApiControllers(apiConfig);
    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
    container.Verify();
    DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(container));
    apiConfig.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container);
    return container;
}

和startup.cs文件

public void Configuration(IAppBuilder app)
{
    // This is a self hosted webapi project..
    HttpConfiguration apiConfig = new HttpConfiguration();
    // confgi oauth
    OAuthConfig.Register(app);
    // simple injector
    var container = SimpleInjectorConfig.Register(apiConfig);
    AutoMapperConfig.RegisterMappings();
    AreaRegistration.RegisterAllAreas();
    WebApiConfig.Register(apiConfig, container);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
    app.UseWebApi(apiConfig);
}

如何在web api中注入ihttprouteconstrint ?

更新:

所以我看了一下DefaultInlineConstraintResolver类的实现,发现这个类不使用容器解析器,而是使用Activator类来创建实例,这可能会导致默认构造函数实例的问题。

你可能需要为IInlineConstraintResolver创建一个自定义实现,或者从DynamicRouteConstraint构造函数中删除参数iddynamicrouteservice,并通过其他方式初始化实例。