Olivier Jacot-Desc ist absolut auf dem richtigen Weg (+1 dafür). Das einzige, was in seiner Antwort fehlt, ist das Laden der korrekten Implementierungen aus der Konfiguration.
Es gibt viele Möglichkeiten, dies zu tun, zum Beispiel, indem Sie den Typnamen in der Konfiguration speichern, aber Sie können auch einen einfacheren Ansatz wählen, z. B. einen einfachen booleschen Wert in der Konfiguration speichern.
IProvider providerX = GetProviderFromConfig();
IHandler handlerZ = GetHandlerFromConfig();
IPreProcessor preProcessorY = GetProcessorFromConfig();
var provider =
new ProviderWrapper(providerX, preProcessorY, handlerZ);
private static IProvider GetProviderFromConfig()
{
if (ConfigurationManager.AppSettings["provider"] == "mail")
{
return new MailProvider();
}
else
{
return new FtpProvider();
}
}
// implement GetHandlerFromConfig just like
// the GetProvider.
UPDATE
Wenn Sie viele Arten haben zwischen zu schalten, den Namen des Typs Speicherung könnte eine bessere Wahl sein:
private static IProvider GetProviderFromConfig()
{
string typeName =
ConfigurationManager.AppSettings["provider"];
Type providerType = Type.GetType(typeName);
return (IProvider)
Activator.CreateInstance(providerType);
}
UPDATE 2
Hier finden Sie ein Beispiel, wie Sie dies mit einem DI-Container konfigurieren können.Ich verwende Simple Injector (mit extensions), aber jeder Behälter tun (auch wenn die Art und Weise zu konfigurieren, wird pro Behälter unterscheiden):
Anmeldung:
using SimpleInjector;
using SimpleInjector.Extensions;
Type providerType = Type.GetType(
ConfigurationManager.AppSettings["provider"]);
Type handlerType = Type.GetType(
ConfigurationManager.AppSettings["handler"]);
Type processorType = Type.GetType(
ConfigurationManager.AppSettings["preProcessor"]);
var container = new Container();
container.Register(typeof(IProvider), providerType);
container.Register(typeof(IHandler), handlerType);
container.Register(typeof(IPreProcessor), processorType);
einen Anbieter auflösen:
var provider = container.GetInstance<IPovider>();
Tipp: Wenn Sie Konstruktorinjektion verwenden, müssen Sie die Typen nicht per Hand verdrahten, der Container erledigt dies für Sie. Zum Beispiel, wenn Ihre MailProvider
so aussieht, ist der Behälter der Lage, die benötigten Abhängigkeiten (IHandler
und IPreProcessor
) durch den Konstruktor zu injizieren:
public class MailProvider : IProvider
{
private readonly IHandler handler;
private readonly IPreProcessor preProcessor;
public MailProvider(IHandler handler,
IPreProcessor preProcessor)
{
this.handler = handler;
this.preProcessor = preProcessor;
}
public void SomeAction() { ... }
}
Diese Frage vage. Es ist mir unklar, was Sie genau wissen wollen. – Steven
was ich suche ist das: – doubleM
@Steven, was ich suche ist das: sagen wir, ich habe zwei verschiedene Providor MailProvider und FTPProvider (beide implementieren IProvider) und zwei verschiedene Handler-Klassen, ZipFilesHandler und RARFileHandle (implementieren Sie IHandler). Theoretisch habe ich vier Möglichkeiten, neue Objekte zu erstellen (MailProvider mit ZipFileHandler-Funktionalität, MailProvider mit RARFileHandler-Funktionalität, FTPProvider mit ZipFileHandler usw.). Wie kann ich das richtige Objekt in Runtime – doubleM