2012-09-03 7 views
8

Ich verwende Ninject als IoC-Container in meinem Projekt. Ich habe folgende Klasse:Convention-basierte Bindung von Konstruktor String-Argumente mit Ninject

public class SomeRepository:ISomeRepository 
{ 
    public SomeRepository(string someDatabaseConnectionString) 
    { 
     // some code here.. 
    } 
} 

In meiner Anwendung Einstellungen Datei habe ich Verbindungszeichenfolge namens "someDatabase". Standardmäßig sollte die eine folgende Konfiguration hinzufügen, um diese Verbindungszeichenfolge in den Konstruktor zu injizieren:

kernel.Bind<ISomeRepository>() 
    .To<SomeRepository>() 
    .WithConstructorArgument("someDatabaseConnectionString", connString); 

Aber ich möchte Bindung solcher Strings herkömmlichen umzusetzen berechnet. Werte für alle Konstruktorparameter des Stringtyps, deren Name mit "ConnectionString" endet, sollten dem Konfigurationsabschnitt connectionStrings der Anwendung entnommen und automatisch eingefügt werden. Ich möchte ähnliche Konvention für appSettings Abschnitt auch implementieren. Dieser Ansatz wird in näheren Einzelheiten in Mark Seemans Artikel "Primitive Dependencies" (Abschnitt "Konventionen für Grundelemente") beschrieben. Castle Windsor Container wurde in Beispielen verwendet.

Ist es möglich, solche Konventionen mit Ninject zu implementieren und was ist der beste Weg, dies zu tun? Ich habe ninject.extensions.conventions bereits ausprobiert, scheint aber keine solche Funktionalität zu haben, oder?

+0

Können Sie ConfigurationManager.AppSettings ["someDatabaseConnectionString"] verwenden? – Ben

+0

Momentan verwende ich ConfigurationManager.AppSettings ["someDatabaseConnectionString"]. Aber stellen Sie sich vor, Sie haben 20 oder mehr Klassen, die von Verbindungszeichenfolgen abhängig sind. Ich möchte keine spezifische Regel für jede dieser Klassen schreiben, ich möchte Abhängigkeiten automatisch injizieren. –

Antwort

1

Es sieht nicht so aus, als ob eine solche Konventionsbindung jetzt mit Ninject möglich ist. I had a similar question here und der Vorschlag war, eine Schnittstelle zu machen, um die Verbindungszeichenfolge zurückzugeben und diese als Parameter zu haben. Das könnte für viele verschiedene Verbindungszeichenfolgen jedoch mühsam sein.

Dies ist nur ein Gedanke, aber könnten Sie ein IConnectionStringProvider<T> haben, die Reflexion verwenden könnte den Namen von T zu erhalten und die Anwendung auf diese Weise nachschlagen Einstellung? Vielleicht so:

public class ConnectionStringProvider<T> : IConnectionStringProvider<T> 
{ 
    public string Value 
    { 
     // use reflection to get name of T 
     // look up connection string based on the name 
     // return the connection string 
    } 
} 
... 
public class SomeRepository:ISomeRepository 
{ 
    public SomeRepository(IConnectionStringProvider<SomeRepository> connectionStringProvider) 
    { 
     this.connectionString = connectionStringProvider.Value; 
    } 
} 

Auch wenn das nicht funktioniert, könnten Sie eine nicht-generic IConnectionStringProvider haben, die einen Typ wie das Argument:

public class ConnectionStringProvider : IConnectionStringProvider 
{ 
    public string GetValueFor(Type type) 
    { 
     // use reflection to get name of type 
     // look up connection string based on the name 
     // return the connection string 
    } 
} 
... 
public class SomeRepository:ISomeRepository 
{ 
    public SomeRepository(IConnectionStringProvider connectionStringProvider) 
    { 
     this.connectionString = connectionStringProvider.GetValueFor(this.GetType()); 
    } 
} 

Wenn eines dieser Werke dann würden sie haben den Vorteil, dass sie mit jedem DI-Container arbeiten sollten.

Verwandte Themen