2013-03-11 14 views
11

To pytanie nie jest związane z programem Ninject. Jest to raczej ogólne pytanie o kodowanie, ale zamieszczam je tutaj, na wypadek, gdyby mógł być lepszy sposób obsługi problemu w programie Ninject niż to, co próbuję zrobić.Uzyskiwanie dostępu do jądra programu Nin 2012 na całym świecie

Chciałbym wiedzieć, czy możliwy jest dostęp do jądra Ninped Standard na całym świecie, od jego instancji w Global.asax.

Oto kod:

public class MvcApplication : NinjectHttpApplication 
{ 
    protected override void OnApplicationStarted() 
    { 
     base.OnApplicationStarted(); 

     // MVC global registration, routing and filtering code goes here... 
    } 

    protected override IKernel CreateKernel() 
    { 
     return Container; 
    } 

    private static IKernel Container 
    { 
     get 
     { 
      IKernel kernel = new StandardKernel(); 
      kernel.Load(new ServiceModule(), new RepositoryModule()); 
      return kernel; 
     } 
    } 
} 

Jeśli mam jakieś zajęcia, na przykład zajęcia elewacyjne, które nie Interfejs z kontrolerów, których chciałbym zacząć łańcuch zależności, moje rozumienie jest Powinienem zastosowanie:

_className = kernel.Get<IClassName>(); 

jednak jedynym sposobem, wiem, aby to zrobić, aby utworzyć nową instancję Ninject jądra standardowego, ale jeśli dobrze rozumiem, to nie jest dobry pomysł, aby utworzyć nową instancję jądro Ninject, ponieważ w zasadzie to tworzy drugi ke rnel.

Czy możliwe jest uzyskanie dostępu do istniejącego jądra, które zostało utworzone w Global.asax na początku aplikacji, z dowolnego miejsca w mojej aplikacji, lub czy istnieje lepszy sposób na zrobienie tego?

Pozdrawiam,

Fred Chateau

Odpowiedz

0

Brzmi jakbyś potrzebował więcej implementacji wzorca Fabryka Ninject. Możesz przenieść jądro z Global.asax na klasę Factory, z którą może współpracować reszta aplikacji.

Alternatywnie, jeśli istnieje sytuacja, w której parametr określony w środowisku wykonawczym służy do określenia powiązań interfejsu, można zawinąć usługę. Jest to hybrydowa konfiguracja DI i ServiceLocater, ale ServiceLocater występuje tylko na instancji poziomu usług, wszystkie pozostałe warstwy są kodowane normalnie we wzorcu DI/IOC.

MyService : IService1 
{ 
    public void DoSomething(MyCustomParameter parameter) 
    { 
     //Builds the Kernel using the supplied parameter 
     //We've in our resolver bound IService1 To MyActualService 
     var trueService = kernel.Get<IService1>(); 
     return trueService.DoSomething(parameter); 
    } 
} 

MyActualService : IService1 
{ 
    public void DoSomething() 
    { 
     //Do the Actual work 
    } 
} 
+1

Czy pan wie, jak utworzenie dla fabryki będzie mieć wpływ na realizację MVC Extensions? –

+0

Niestety, ta część nie wiedziałabym bez jej próby. Użyłem powyższej metody owijania dla aplikacji, nad którą pracuję, ze względu na wyjątkowe obawy i wybór architektury. – Kaiser12

1

Udało mi się uruchomić Service Locator i wygląda na to, że działa całkiem dobrze. Gdy żądanie wchodzi do aplikacji za pomocą metody działania kontrolera MVC, funkcja Ninject działa w normalny sposób dostarczany przez Ninject.Mvc.Extensions. Wprowadza klasy instancji za pomocą konstruktora kontrolera. Gdy żądanie wchodzi do aplikacji w jakikolwiek inny sposób, wywołuję usługę lokalizatora, aby dostarczyć klasy instancji w tym konstruktorze klas.

Oto kod:

pierwsze, odniesienie do Microsoft.Practices.ServiceLocation

A po Ninject klasa adaptera.

public class NinjectServiceLocator : ServiceLocatorImplBase 
{ 
    public IKernel Kernel { get; private set; } 

    public NinjectServiceLocator(IKernel kernel) 
    { 
     Kernel = kernel; 
    } 

    protected override object DoGetInstance(Type serviceType, string key) 
    { 
     return Kernel.Get(serviceType, key); 
    } 

    protected override IEnumerable<object> DoGetAllInstances(Type serviceType) 
    { 
     return Kernel.GetAll(serviceType); 
    } 
} 

A w Global.asax

public class MvcApplication : NinjectHttpApplication 
{ 
    private static IKernel _kernel; 


    protected override IKernel CreateKernel() 
    { 
     return Container; 
    } 

    private static IKernel Container 
    { 
     get 
     { 
      if (_kernel == null) 
      { 
       _kernel = new StandardKernel(); 
       _kernel.Load(new ServiceModule(), new RepositoryModule()); 

       ServiceLocator.SetLocatorProvider(() => new NinjectServiceLocator(_kernel)); 
      } 

      return _kernel; 
     } 
    } 
} 

Uwaga ten kod wymaga użycia Ninject.Mvc.Extensions, który stanowi zależność rozpoznawania fallback do sterownika domyślnego. W przeciwnym razie może być wymagany niestandardowy przelicznik zależności.

To wydaje się rozwiązywać wszystkie moje obawy.Tworzy klasy instancji, rozpatruje cały wykres obiektów i działa z dowolnego miejsca, w którym jest to potrzebne. I, o ile wiem, istnieje tylko jedno jądro Ninject Standard na aplikację.

Wiem, że używanie wzorca Lokalizacji Usług jest niezadowolone, ale wyobrażam sobie, że używanie więcej niż jednego jądra może być jeszcze gorsze.

Fred Chateau

20

Najprostszym sposobem (IMO):

_className = (IClassName)System.Web.Mvc.DependencyResolver.Current.GetService(typeof(IClassName)); 
2

Nowsza wersja Ninject ma tę metodę, jeśli używane z System.Web.MVC:

var obj = DependencyResolver.Current.GetService<IClassName>();

Chyba, że ​​będziesz musiał manipulować powiązaniami DI w locie, ale tworzenie instancji StandardKernel jest trochę ciężkie.

IKernel kernel = new StandardKernel(); var obj = DependencyResolver.Current.GetService<IClassName>();

Powiązane problemy