2013-06-25 8 views
7

Mam usługę używaną przez kilka kontrolerów w moim projekcie WebAPI. Usługa musi generować adresy URL, więc najlepiej byłoby uzyskać parametr UrlHelper za pośrednictwem parametru konstruktora.Wstrzyknięcie interfejsu WebAPI UrlHelper do usługi za pomocą Autofac

public class MyService 
{ 
    public MyService(UrlHelper urlHelper) { ... } 
} 

Używam Autofac jako mojego kontenera IoC. Jak mogę zarejestrować UrlHelper w kontenerze? Potrzebuje HttpRequestMessage i nie mogę wymyślić, jak uzyskać "aktualny" komunikat.

+0

spojrzeć na to, co pracują na dla WebAPIBook, ma jedno możliwe rozwiązanie do tego problemu ... https://gist.github.com/glennblock/8f18bdee15eec9c1af70 –

+0

Ah, tak, bardzo miło. Myślałem o stworzeniu programu do obsługi wiadomości, aby rozwiązać ten problem. Postaram się go zrobić. Dzięki. –

Odpowiedz

6

Użyj metody RegisterHttpRequestMessage zarejestrować aktualny wniosek, a następnie można również zarejestrować pomocnika URL tak:

public static IContainer SetupContainer(HttpConfiguration config) 
{ 
    var containerBuilder = new ContainerBuilder(); 

    // Register your Web API. 
    containerBuilder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 
    containerBuilder.RegisterHttpRequestMessage(config); 
    containerBuilder.Register(x => new UrlHelper(x.Resolve<HttpRequestMessage>())); 
    containerBuilder.RegisterWebApiFilterProvider(config); 
    containerBuilder.RegisterWebApiModelBinderProvider(); 

    // Register your other types... 

    var container = containerBuilder.Build(); 

    // Set the dependency resolver to be Autofac. 
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container); 

    return container; 
} 
+0

autowiring właściwości kontrolerów api nie działa z RegisterHttpRequestMessage. tj. RegisterApiControllers (Assembly.GetExecutingAssembly()). PropertiesAutnostred(). Jeśli użyjesz tego kodu, utracisz opcję autowirowania właściwości. – Mick

0

Najlepszy mogę myśleć to zrobić usługa wdrożenia IAutofacActionFilter jak tak

public class MyService : IAutofacActionFilter 
    { 
     private UrlHelper _urlHelper; 

     public void DoSomething() 
     { 
      var link = Url.Link("SomeRoute", new {}); 
     } 

     private UrlHelper Url 
     { 
      get 
      { 
       if(_urlHelper == null) 
        throw new InvalidOperationException(); 

       return _urlHelper; 
      } 
     } 

     public void OnActionExecuted(System.Web.Http.Filters.HttpActionExecutedContext actionExecutedContext) 
     {    
     } 

     public void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext) 
     { 
      this._urlHelper = actionContext.Request.GetUrlHelper(); 
     } 
    } 

a następnie użyć coś jak na poniższym Autofac config

builder.RegisterType<MyService>() 
       .AsWebApiActionFilterFor<SomeController>() 
       .AsSelf() 
       .InstancePerApiRequest(); 
4

podstawie komentarzu Darrel Millera, stworzyłem następujące :

Prosta klasa kontenerów przechowująca odwołanie do "bieżącego" HttpRequestMessage

public class CurrentRequest 
{ 
    public HttpRequestMessage Value { get; set; } 
} 

Procedura obsługi wiadomości, która będzie przechowywać bieżącego żądania

public class CurrentRequestHandler : DelegatingHandler 
{ 
    protected async override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
    { 
     var scope = request.GetDependencyScope(); 
     var currentRequest = (CurrentRequest)scope.GetService(typeof(CurrentRequest)); 
     currentRequest.Value = request; 
     return await base.SendAsync(request, cancellationToken); 
    } 
} 

W Global.asax, podczas konfigurowania WebAPI, dodaj obsługi wiadomości.

GlobalConfiguration.Configuration.MessageHandlers.Insert(0, new CurrentRequestHandler()); 

Następnie należy skonfigurować pojemnik Autofac pozwolić mu zbudować UrlHelper, uzyskanie bieżącego żądania od obiektu CurrentRequest.

var builder = new ContainerBuilder(); 
builder.RegisterType<CurrentRequest>().InstancePerApiRequest(); 
builder.Register(c => new UrlHelper(c.Resolve<CurrentRequest>().Value)); 
builder.RegisterType<MyService>(); 
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 
... 
container = builder.Build(); 

UrlHelper można następnie wstrzykiwane do MyService tak jak każde inne uzależnienie.

Dziękuję Darrel za skierowanie mnie we właściwym kierunku.

+8

Właśnie dodałem obsługę wtrysku zależności HttpRequestMessage do Autofac.WebApi i zostanie ona dołączona do następnej wersji. https://code.google.com/p/autofac/source/detail?r=60d369499963b89224c1f682cfbf8592eae95342 –

+0

nie mogłem dostać RegisterHttpRequestMessage pracować jednak ten kod nie praca – Mick

Powiązane problemy