5

正如標題所述,我需要能夠將服務注入到web api約束類中。我在我的c#webApi項目中使用SimpleInjector。你怎麼注入一個web api IHttpRouteConstraint?

在我webApiConfig.cs我有這個

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

// routing 
config.MapHttpAttributeRoutes(constraintResolver); 

我定製contraint看起來像這樣

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()); 
    } 
} 

正如你所看到的,我需要的IDynamicRouteService注入到我的約束。目前我的應用程序拋出錯誤說

沒有爲此對象定義的無參數構造函數。

但我不想要一個無參數的構造函數,因爲我需要注入服務。

我已經加入這一行到我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服務注入作爲運作良好,我只是需要能夠注入IDynamicRouteService到我的約束。

任何幫助表示讚賞

編輯

這是我目前的SimpleInjector註冊方法

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); 
} 
+0

您正在使用[webAPI-SimpleInjector集成](https://www.nuget.org/packages/SimpleInjector.Integration.WebApi)包是否正確? – vendettamit

+0

是的,我相信我是 – Gillardo

+0

檢查我的答案,如果我猜對了。所以你使用的是SimpleInjector,但是還有另一個關聯庫,它與SimpleInjector的WebAPI集成包一起提供,它實際上通過提供WebApi兼容容器來滿足需求。 – vendettamit

回答

3

更新:

所以我看着DefaultInlineConstraintResolver類的實現,發現此類不使用集裝箱解析器,但使用激活類來創建實例,它可能會引起你的默認構造方法的問題實例。

IMO您可能需要爲IInlineConstraintResolver創建自定義實現,或從DynamicRouteConstraint構造函數中刪除參數IDynamicRouteService並以其他方式初始化實例。

+0

謝謝!更新了答案。 – vendettamit