2012-11-05 10 views

Odpowiedz

5

Jednym ze sposobów na osiągnięcie tego, który ja często dla wygody jest zadeklarować swój pojemnik jako zmienną globalną w swoim Global.ascx.cs złożyć jak:

public class MvcApplication : System.Web.HttpApplication 
{ 
    public static UnityContainer Container; 

    protected void Application_Start() 
    { 
     // assuming your initialize here 
    } 
} 

Jednak jest to dość hack- ish.

Poprawną rzeczą byłoby użycie Unity do rozwiązania kontrolerów (See this article on creating a unity controller factory), a następnie pozwolić jedności na wstrzyknięcie jakichkolwiek zależności do kontrolera, gdy rozstrzyga kontroler.

więc kontroler jak:

public MyController: Controller { 

public ICacheManager CacheManager {get;set;} 

} 

Czy automagicznie rezolwer wszelkie zależności, że pojemnik jest zarejestrowane.

+0

Dziękujemy! Dokładnie to, czego potrzebuję. – Sergey

6

Ja zakładając, że” ponowne rozwiązywanie instancji kontrolera za pomocą kontenera. W takim przypadku kontroler może odbierać IUnityContainer jako zależność, tak jak każdą inną.

Co próbujesz osiągnąć? Założenie kontenera w rozwiązanych klasach nie jest wspaniałe, ponieważ łączy klasy z kontenerem i zwykle można je zastąpić innymi mechanizmami.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var container = new UnityContainer(); 

     var foo = container.Resolve<MyController>(); 
    } 
} 

public class MyController 
{ 
    private IUnityContainer container; 

    public MyController(IUnityContainer container) 
    { 
     this.container = container; 
    } 
} 
3

Chociaż jest to możliwe, najlepiej go unikać.

Najlepiej, jeśli weźmiesz pod uwagę zależności wymagane przez kontroler za pomocą parametrów konstruktora. W ten sposób klasa (kontroler) wyjaśnia, jakie są zależności wymagane do jej uruchomienia.

Jeśli skonfigurowano poprawnie, kontener poda te zależności i ich zależności (jeśli istnieją) i tak dalej.

Stosowanie kontenera IoC powinno zazwyczaj być ograniczone tylko do jednego miejsca wewnątrz aplikacji (zwanego korzeń kompozycji). Każde dodatkowe odwołanie/wezwanie do kontenera jest podatne na doprowadzenie do Service Locator anti-pattern. Zobacz powiązany artykuł z powodów, dla których takie podejście może być złe.

+0

Biorąc pod uwagę "anty-wzorzec lokalizatora usług", w jaki sposób wykorzystać pojemnik rozwiązać bez lokalizatora serwisowego, aby rozwiązać problem? – enorl76

+0

@ enorl76 Twoje połączenia z 'container.Resolve()' powinny być ograniczone do jednego miejsca w aplikacji, jak opisałem w odpowiedzi. Komponenty biznesowe powinny być nieświadome, że są one wstrzykiwane. – GolfWolf

+0

Problem, nad którym się zastanawiam, to sytuacja, w której komponent biznesowy potrzebuje innego tylko podczas określonego przepływu pracy, ale uważam, że odpowiedź prawdopodobnie polega na refaktoryzacji komponentów biznesowych w miejscu, w którym określony przepływ pracy zostałby zamknięty w komponencie biznesowym z wyraźnym konstruktorem z siostrą. komponent biznesowy jako zależność od konstruktora. – enorl76

8

Nie wiem, dlaczego trzeba, ale tutaj jest kod:

public ActionResult Area51() 
    { 
     var _service = DependencyResolver.Current.GetService(typeof (IDummyService)); 

     return View(); 
    } 

Jeśli to, co staramy się zrobić to wstrzykiwanie kontrolera, należy ustawić DepedencyResolver korzystać z kontenera IoC w uruchomieniu aplikacji global.asax za . Następnie MVC automatycznie wstrzyknie zależność do kontrolera.

var container = new UnityContainer(); 
DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container)); 

Spójrz tutaj, aby uzyskać więcej przykład:

http://www.dotnet-tricks.com/Tutorial/dependencyinjection/632V140413-Dependency-Injection-in-ASP.NET-MVC-4-using-Unity-IoC-Container.html

Powiązane problemy