2012-11-05 6 views

Antwort

5

Eine Möglichkeit, dies zu tun, die ich oft für Bequemlichkeit zu tun ist Ihr Container als globale Variable in Ihrer Global.ascx.cs wie Datei zu deklarieren:

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

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

Dies ist jedoch ziemlich Hack- ish.

Die richtige Lösung wäre, Unity zu verwenden, um Ihre Controller aufzulösen (See this article on creating a unity controller factory), und dann zuzulassen, dass alle Abhängigkeiten in den Controller injiziert werden, wenn der Controller aufgelöst wird.

So ein Controller wie:

public MyController: Controller { 

public ICacheManager CacheManager {get;set;} 

} 

Würde automatisch alle Abhängigkeiten Resolver, dass Ihr Behälter registriert hat.

+0

Thank you! Genau das, was ich brauche. – Sergey

6

Ich nehme an, Sie‘ Erneutes Auflösen einer Controller-Instanz mithilfe des Containers. Wenn dies der Fall ist, können Sie den Controller veranlassen, den IUnityContainer als eine Abhängigkeit wie jede andere zu erhalten.

Was möchten Sie erreichen? Es ist nicht gut, den Container in Ihren aufgelösten Klassen zu finden, da er Ihre Klassen mit dem Container koppelt und normalerweise durch andere Mechanismen ersetzt werden kann.

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

Obwohl es möglich ist, ist es das Beste, dass Sie es vermeiden.

Am besten nehmen Sie Abhängigkeiten, die der Controller über Konstruktorparameter benötigt. Auf diese Weise macht die Klasse (Controller) deutlich, welche Abhängigkeiten für die Ausführung benötigt werden.

Wenn der Container korrekt konfiguriert ist, stellt er die Abhängigkeiten und deren Abhängigkeiten bereit (falls vorhanden) und so weiter.

Die Verwendung eines IoC-Containers sollte normalerweise auf nur einen Platz innerhalb einer Anwendung beschränkt sein (Composition Root). Jede zusätzliche Referenz/Aufruf an den Container ist anfällig für die Service Locator anti-pattern führen. In dem verlinkten Artikel finden Sie Gründe, warum ein solcher Ansatz schlecht sein kann.

+0

Angesichts dieser "Service Locator Anti-Pattern", wie verwendet man den Container Resolve ohne einen Service Locator, um den Container aufzulösen? – enorl76

+0

@ enorl76 Ihre Aufrufe von 'container.Resolve()' sollten auf einen Platz in der Anwendung beschränkt sein, wie ich in der Antwort beschrieben habe. Ihre Geschäftskomponenten sollten nicht wissen, dass sie und ihre Abhängigkeiten injiziert werden. – GolfWolf

+0

Das Problem, über das ich mich frage, ist, wenn eine Geschäftskomponente eine andere nur während eines bestimmten Arbeitsablaufs benötigt, aber ich glaube, die Antwort ist wahrscheinlich die Geschäftskomponenten leicht umstrukturieren, wo der bestimmte Workflow in einer Geschäftskomponente mit einem expliziten Konstruktor mit der Schwester eingekapselt wäre Business-Komponente als Konstruktorabhängigkeit. – enorl76

8

nicht sicher, warum Sie brauchen das, aber hier ist der Code:

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

     return View(); 
    } 

Wenn das, was Sie versuchen zu tun ist, eine Controller-Injektion, sollten Sie DepedencyResolver setzen Ihre IoC-Container in Global.asax der Anwendung Start zu verwenden, . Dann wird MVC Abhängigkeit automatisch Ihrem Controller injizieren.

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

Schauen Sie hier für weiteres Beispiel:

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

Verwandte Themen