2009-08-12 16 views
0

ich eine Web-Anwendung starten, die folgenden Projekte enthält:Dependency Injection Abfrage

Booking.Web Booking.Services Booking.DataObjects Booking.Data

Ich verwende die Repository-Muster in mein Datenprojekt nur. Alle Dienste werden gleich sein, egal was passiert. Wenn ein Kunde jedoch Access verwenden möchte, verwendet er ein anderes Datenrepository als wenn der Kunde SQL Server verwenden möchte.

Ich habe StructureMap, und wollen in der Lage sein, wie folgt vorgehen:

Webprojekt ist nicht betroffen. Es ist eine Webformular-Anwendung, die nur über das Projekt services und das Projekt dataobjects informiert.

Wenn ein Dienst aufgerufen wird, verwendet er StructureMap (indem er die Datei bootstrapper.cs nachschlägt), um zu sehen, welches Datenrepository verwendet werden soll.

Ein Beispiel für eine Dienste-Klasse ist die Fehlerprotokollierung Klasse:

public class ErrorLog : IErrorLog 
{ 
    ILogging logger; 

    public ErrorLog() 
    { 

    } 

    public ErrorLog(ILogging logger) 
    { 
     this.logger = logger; 
    } 

    public void AddToLog(string errorMessage) 
    { 
     try 
     { 
      AddToDatabaseLog(errorMessage); 
     } 

     catch (Exception ex) 
     { 
      AddToFileLog(ex.Message); 
     } 

     finally 
     { 
      AddToFileLog(errorMessage); 
     } 
    } 

    private void AddToDatabaseLog(string errorMessage) 
    { 
     ErrorObject error = 
      new ErrorObject 
      { 
       ErrorDateTime = DateTime.Now, 
       ErrorMessage = errorMessage 
      }; 

     logger.Insert(error); 
    } 

    private void AddToFileLog(string errorMessage) 
    { 
     // TODO: Take this value from the web.config instead of hard coding it 
     TextWriter writer = new StreamWriter(@"E:\Work\Booking\Booking\Booking.Web\Logs\ErrorLog.txt", true); 
     writer.WriteLine(DateTime.Now.ToString() + " ---------- " + errorMessage); 
     writer.Close(); 
    } 
} 

Ich mag diesen Dienst rufen können, von meinem Web-Projekt, ohne zu definieren, welche Repository für den Datenzugriff zu verwenden. Mein boostrapper.cs im Dienste Projektdatei wird wie folgt definiert:

public class Bootstrapper 
{ 
    public static void ConfigureStructureMap() 
    { 
     ObjectFactory.Initialize(x => 
     { 
      x.AddRegistry(new ServiceRegistry()); 
     } 
     ); 
    } 

    public class ServiceRegistry : Registry 
    { 
     protected override void configure() 
     { 
      ForRequestedType<IErrorLog>().TheDefaultIsConcreteType<Booking.Services.Logging.ErrorLog>(); 
      ForRequestedType<ILogging>().TheDefaultIsConcreteType<SqlServerLoggingProvider>(); 
     } 
    } 
} 

Was muss ich diese Arbeit bekommen? Als ich einen Test definiert habe, war das ILogger-Objekt null.

+0

einen Blick auf diese Antwort nehmen: http://stackoverflow.com/questions/589374/how-to-use-dependency -injektion-mit-asp-net/3849338 # 3849338 – Steven

Antwort

0

Vielleicht wären einige Details nützlich, wie Sie diesen Code aus einem Test aufrufen.

Mein Verständnis ist, dass Sie sicherstellen müssen, dass der ConfigureStructureMap-Aufruf früh im Leben der Anwendungen (z. B. in der Global.asax in einem Webprojekt) vorgenommen wurde.

Danach können Sie für Instanzen von IErrorLog anrufen würde mit so etwas wie:

IErrorLog log = StructureMap.ObjectFactory.GetNamedInstance<IErrorLog>();