2012-02-23 13 views
11

Utknąłem. Użyłem metody opisanej tutaj dla wcf web api p6 Ninject working with WCF Web API Preview 5, jednak rzeczy są całkiem inne z implementacją mvc w wersji beta. Tutaj jest dobry artykuł o nazwie http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver, który mówi o budowaniu własnego niestandardowego narzędzia do rozwiązywania zależności, ale chciałbym użyć tej samej implementacji, której używam dla moich kontrolerów widoku mvc ... np. Ninject. Próbowałem kilku rzeczy na podstawie przykładu IoC Unity również w tym artykule, ale nic jeszcze nie zostało wyjaśnione. Każda pomoc wskazująca mi we właściwym kierunku byłaby bardzo doceniana. Zamierzam też dalej kopać na własną rękę. Z góry dziękuję!Używanie programu Ninject z interfejsem API ASP.NET Beta ApiController

Oto, gdzie jestem. Używałem programu WebActivator do bootstrapowania kodu, ale od tego czasu upuściłem go do Application_Start() tylko po to, aby wyciągnąć jeszcze jedną rzecz z równania.

protected void Application_Start() 
    { 
     var kernel = new StandardKernel(new MyNinjectModule()); 
     GlobalConfiguration.Configuration.ServiceResolver.SetResolver(new NinjectDependencyResolver(kernel)); 
    } 

I otrzymuję następujący błąd:
Typ Ninject.Web.Mvc.NinjectDependencyResolver nie wydaje się wdrożenie Microsoft.Practices.ServiceLocation.IServiceLocator. Nazwa
Parametr: commonServiceLocator

Znaleziono rozwiązanie
może jest/będzie bardziej elegancki sposób, ale teraz pracuje dla mnie. Dodaję tu również moją niestandardową procedurę obsługi komunikatów.

[assembly: WebActivator.PreApplicationStartMethod(typeof(MyApp.AppStart.ApiBootstrapper), "Start")] 
namespace MyApp.AppStart 
{ 
    public class ApiBootstrapper 
    { 
     public static void Start() 
     { 
      var kernel = new StandardKernel(new MyNinjectModule()); 
      var resolver = new NinjectDependencyResolver(kernel); 
      GlobalConfiguration.Configuration.ServiceResolver.SetResolver(resolver.GetService, resolver.GetServices); 
      GlobalConfiguration.Configuration.MessageHandlers.Add(new ApiAuthHandler()); 
     } 
    } 
} 
+0

Jest to dość miłe rozwiązanie: http://haacked.com/archive/2012/03/11/itrsquos- the-little-things-about-asp-net-mvc-4.aspx –

+0

również sprawdź pakiet @Remo Gloor poniżej, jeśli chcesz używać tych samych wiązań dla obu typów kontrolerów. Możesz go znaleźć na github i zainstalować z nuget. –

Odpowiedz

3

nigdy nie użyłem WebAPI ale ponieważ semantyczny z IDependencyResolver jest dokładnie taki sam jak ten z MVC3 powinieneś być w stanie korzystać z tego samego realizacji: https://github.com/ninject/ninject.web.mvc/blob/master/mvc3/src/Ninject.Web.Mvc/NinjectDependencyResolver.cs

UPDATE: The Ninject.Web Rozszerzenie .WebAPi dodaje obsługę ApiControllers

+2

To jest właściwie jedna z rzeczy, którą próbowałem, bez żadnej radości niestety. na przykład ServiceResolver.SetResolver (new NinjectDependencyResolver (kernel)) generuje następujący błąd: _Ninject.Web.Mvc.NinjectDependencyResolver nie wydaje się implementować Microsoft.Practices.ServiceLocation.IServiceLocator_ –

+0

Rozwiązaniem było ostatecznie użycie klasy ninjectdepencyresolver, właśnie miałem używać alternatywnego podpisu metody na setresolver. Dziękuję za odpowiedź! –

0

Może brzmieć głupio, ale czy masz pewność, że masz odniesienie do pakietu nuget CommonServiceLocator/CommonServiceLocator.NinjectAdapter lub skojarzonych złożeń. Twój NinjectDependencyResolver może nie być w stanie rozwiązać odniesienia do IServiceLocator.

+0

Zainstalowałem oba pakiety, ale wciąż nie mam szczęścia. Możesz zobaczyć, jak pakiet ninject.mvc obecnie podłącza się przez niestandardowy bootstrapper za pomocą webactivatora ... ale musi być poza cyklem życia żądania apicontrollera, ponieważ żądanie to nie trafia bezpośrednio do kontrolera ... jego stworzony dla ciebie przez ramy. –

+0

Problem polegał na tym, że mój kod rozwiązał tę metodę podpisu http://msdn.microsoft.com/en-us/library/hh835505(v=vs.108).aspx, gdy myślałem, że używa tego http:// /msdn.microsoft.com/en-us/library/hh835218(v=vs.108).aspx. Na szczęście istnieje trzecia opcja, która rozwiązuje problem typu. Dzięki za odpowiedź Hamaze! –

1

Znalazłem odpowiedź i zaktualizowałem moje pytanie powyżej z rozwiązaniem. Samo rozwiązanie było mniej lub bardziej obecne w artykule Using the Web API Dependency Resolver, po prostu musiałem ciągle ulepszać program ninject. Obie odpowiedzi pomogły mi szybko zawęzić to dzięki @Remo i @James.

+0

Czy możesz podać przykłady kodu od momentu rozpoczęcia wiązania i reszty kodu adaptera w jednym? –

+1

@ShawnMclean Nie jestem pewien, czy podążam za tobą. W powyższym rozwiązaniu używam pakietu nuget w webactivator na niestandardowej klasie, aby zarejestrować resolver zależny ninject z webapi (definiując moje powiązania w oddzielnej klasie pochodnej ninjectmodule). Możesz również wziąć ten sam kod metodyczny i umieścić go w swoich plikach global.asax Application_Start(), po prostu preferuję takie podejście do ładowania. Istnieje również odpowiedź powyżej, która wspomina rozwiązanie Phila Haacka, które zasadniczo pozwala na użycie tych samych powiązań zarówno dla mvc, jak i web api. Jednak na razie wolę moją metodę. –

0

Ten sam kod będzie działać zarówno dla MVC, jak i WebApi, jednak ponieważ WebApi został zainspirowany przez MVC, a zestawy MVC nie muszą być przywoływane w celu korzystania z WebApi (lub vice versa), istnieje spora ilość powielania kodu między dwiema strukturami. Jeśli chcesz używać MVC, zależność będzie pochodzić od System.Web.Mvc, jeśli chcesz korzystać z WebApi, użyjesz System.Web.Http. Jeśli chcesz użyć obu, będziesz musiał rozróżnić w swoim kodzie, którego będziesz używał, używając bardziej jawnej rozdzielczości przestrzeni nazw.

W twoim przypadku problem polega na tym, że MVC zajął pierwsze miejsce, a klasa NinjectDependancyResolver dziedziczy po System.Web.Mvc.IDependencyResolver. Będziesz chciał utworzyć dokładny duplikat klasy NinjectDependancyResolver zamiast tego dziedziczy po System.Web.Http.IDependencyResolver. Użyj TEJ klasy, aby ustawić swój IoC, a będziesz gotowy.

+0

dzięki za odpowiedź! Zasadniczo to zrobiłem w powyższej odpowiedzi z powodu problemu z duplikowaniem, który opisujesz. Jednak, ponieważ to przeciążenie istnieje na setresolver http://msdn.microsoft.com/en-us/library/hh834083(v=vs.108).aspx, udało mi się obejść tworzenie duplikatu rozwiązywania zależności ninject, który implementuje system Wersja .web.http interfejsu. Żałuję, że nie wymyślili lepszego sposobu, żeby sobie z tym poradzić. Naprawdę powinienem móc użyć tego samego narzędzia do rozwiązywania zależności dla obu. –

0

Znalazłem ładne rozwiązanie here.

Jest to dość łatwe, jeśli jesteś już przy użyciu Ninject CommonServiceLocator/inicjującego:

private static IKernel CreateKernel() { 
    var kernel = new StandardKernel(); 
    RegisterServices(kernel); 

    GlobalConfiguration.Configuration.ServiceResolver 
     .SetResolver(new NinjectServiceLocator(kernel)); 
    return kernel; 
} 
Powiązane problemy