5

Ich bin auf der Suche nach einem sauberen Muster zu vermeiden, verwenden Abhängigkeiten in .Net Erweiterungsmethoden, ohne explizit newing-up oder mit einem Service Locator:Wie Service-Locator in .net Erweiterungsmethoden

public static class HttpContextExtensions 
{ 
    public static SomeClass ExtensionMethod(this HttpContext context) 
    { 
     //looking to avoid this 
     var dependency = ServiceLocator.GetService<DependencyType>(); 
     return dependency.DoSomething(context); 
    } 
} 

Bin ich Bellen hier den falschen Baum? Sollte ich nach einer direkteren Lösung suchen, die context in eine Methode übergibt? Ich würde gerne eine Erweiterung verwenden, wenn möglich.

Antwort

7

In dem Buch "Dependency Injection in .NET" von Mark Seemann, in Kapitel 2 spricht er über 4 verschiedene Muster der Injektion:

  1. Constructor Injection
  2. Property Injection
  3. Method Injection
  4. Ambient Context

Die 4. ein, Ambient Kontext ist ein statischer Eigenschaft, die von einem abstrakten Typ sein kann. Diese Eigenschaft kann im DI-Stamm, im Threadkontext, im Aufrufkontext, im Anforderungskontext usw. festgelegt werden. .NET-Sicherheit, Transaktionen und andere Dinge wie dieses verwenden dieses Muster.

Hier sind Links, die Ihnen weitere Informationen geben:

Hier einige ist Beispielcode:

public interface IOutput 
{ 
    void Print(Person person); 
} 

public class ConsoleOutput : IOutput 
{ 
    public void Print(Person person) 
    { 
     Console.WriteLine("{0} {1}", person.FirstName, person.LastName); 
    } 
} 

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

public static class SampleContext 
{ 
    public static IOutput Output { get; set; } 
} 

public static class ExtensionMethods 
{ 
    public static void Print(this Person person) 
    { 
     SampleContext.Output.Print(person); 
    } 
} 

static class Program 
{ 
    static void Main() 
    { 
     //You would use your DI framework here 
     SampleContext.Output = new ConsoleOutput(); 

     //Then call the extension method 
     var person = new Person() 
     { 
      FirstName = "Louis-Pierre", 
      LastName = "Beaumont" 
     }; 

     person.Print(); 
    } 
} 
+0

Können Sie einen Beispielcode für Erweiterungsmethoden unter Verwendung des Umgebungskontexts bereitstellen? – Marcos

2

Sie können dafür keine Erweiterungsmethoden verwenden. Erweiterungsmethoden sind statisch und das bedeutet, dass Sie die Konstruktorinjektion nicht verwenden können. Nur Methodeninjektion ist eine Option, aber das bedeutet, dass Sie die Abhängigkeiten als Methodenargumente übergeben müssen und das normalerweise saugt, da Abhängigkeiten normalerweise ein Implementierungsdetail sein sollten, aber Methodeninjektion die Abhängigkeiten Teil des Vertrags macht, was den Consumer der Erweiterungsmethode sollte über diese Abhängigkeiten wissen (und sie injiziert bekommen).

Also die Lösung ist: Verwenden Sie keine Erweiterungsmethoden für alles, was Abhängigkeiten hat: Schreiben Sie eine richtige Klasse und Abstraktion dafür.

+0

Dank @Steven. Das war mein Verdacht. Ich versuche, diese Art von Mustern zu vermeiden, und werde die Orte, an denen ich Erweiterungen mit Abhängigkeiten erstellt habe, erneut besuchen müssen. – Eric

0

Eine mögliche Lösung wäre stattdessen, dass die Erweiterungsmethode die zu injizierende Klasse erweitert und diese Abhängigkeit in einem Upstream-Kontext wie einer Controller-Aktion oder einem anderen nicht statischen Einstiegspunkt referenziert zu diesem Anruf.