5

Come afferma il titolo, devo essere in grado di iniettare un servizio in una classe di vincoli web api. Sto usando SimpleInjector nel mio progetto C# webApi.Come si può iniettare in una API Web IHttpRouteConstraint?

Nei miei webApiConfig.cs ho questo

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

// routing 
config.MapHttpAttributeRoutes(constraintResolver); 

mio contraint personalizzato assomiglia a questo

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

Come potete vedere, ho bisogno di iniettare l'IDynamicRouteService nel mio vincolo. Attualmente la mia applicazione genera un errore dicendo

Nessun costruttore parametrico definito per questo oggetto.

Ma non voglio un costruttore senza parametri poiché ho bisogno del servizio iniettato.

ho già aggiunto questa linea nel mio file SimpleInjectorConfig, in cui mi registro tutte le mie classi di iniettare

container.RegisterWebApiRequest<IDynamicRouteService, DynamicRouteService>(); 

E io ho creato il servizio effettivo, che implementa l'interfaccia, qui è (abbattuto versione)

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

} 

Non c'è niente di sbagliato con il mio servizio IModuleService essere iniettato come che sta lavorando bene, ho solo bisogno di essere in grado di iniettare IDynamicRouteService nel mio vincolo.

Qualsiasi aiuto apprezzato

EDIT

Ecco il mio attuale metodo SimpleInjector Registrati

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

e il file miei 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

Si sta utilizzando il pacchetto [integrazione WebAPI-SimpleInjector] (https://www.nuget.org/packages/SimpleInjector.Integration.WebApi)? – vendettamit

+0

Sì, credo di essere – Gillardo

+0

controllare la mia risposta se ho indovinato giusto. quindi stai usando SimpleInjector, ma c'è un'altra libreria associata che viene fornita con il pacchetto di integrazione WebAPI di SimpleInjector che effettivamente fa il necessario fornendo il contenitore compatibile WebApi. – vendettamit

risposta

3

Aggiornamento:

Così ho guardato l'attuazione di DefaultInlineConstraintResolver di classe e ha scoperto che questa classe non usa il risolutore contenitore ma utilizzando Activator classe per creare l'istanza che potrebbe si essere la causa del problema di costruttore di default esempio.

IMO potrebbe essere necessario creare un'implementazione personalizzata per IInlineConstraintResolver o rimuovere il parametro IDynamicRouteService dal costruttore DynamicRouteConstraint e inizializzare il modulo di istanza in altro modo.

+0

Grazie! Aggiornata la risposta. – vendettamit

Problemi correlati