Fabrik zum Erstellen von Objekten Nach ein Generischer Typ C#
Was wäre der effizienteste Weg zu instantiieren eines Objekts nach einem generischen Typ übergeben, um eine Factory-Klasse, zum Beispiel:
public class LoggerFactory
{
public static ILogger<T> Create<T>()
{
//Switch Statement?
//Generic Dictionary?
//EX.: if "T" is of type "string": return (ILogger<T>)new StringLogger();
}
}
Wie würden Sie es tun? Die Verzweigung Anweisung? etc...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich denke, es ist am besten halten Sie es einfach, vielleicht so etwas wie dieses:
Rufen Sie einfach die
AddLoggerProvider
für jeden Typ, den Sie unterstützen möchten, können verlängert werden, zur Laufzeit, sorgt Sie für Sie auf jeden Fall fügen Sie eine Implementierung der Schnittstelle in die Bibliothek, und nicht ein Objekt, ist nicht sehr schnell, weil derActivator
, aber einen logger nicht wahrscheinlich ein Engpass sowieso. Hoffe, es sieht okay aus.Verwendung:
Hinweis: jeder
ILogger<T>
benötigt einen parameterlosen Konstruktor für dieActivator
, sondern dass auch gewährleistet ist, mit dernew()
generische Einschränkung in der add-Methode.Ich denke, ich würde es so machen:
Zahlen Sie etwas von der Lesbarkeit-Preis (alle Spitzen Klammern, sheesh), aber wie Sie sehen können, macht es für sehr kleine Programm-Logik.
Obwohl ich in der Regel empfehlen die Verwendung eines dependency injection-framework, die Sie implementieren können, etwas mit Reflexion, suchen würde, die verfügbaren Typen für das eine, führt die entsprechende ILogger-Schnittstelle.
Ich würde empfehlen, dass Sie sorgfältig überlegen, welche Baugruppen enthalten, die diese logger-Implementierungen, und wie erweiterbar und Kugel-Beweis-Sie wollen die Lösung zu sein. Durchführung Laufzeit Recherchen über die verfügbaren Baugruppen und-Arten ist nicht Billig. Es ist jedoch eine einfache Möglichkeit, um zu ermöglichen, Erweiterbarkeit in dieser Art von design. Sie vermeiden auch das Problem von up-front-Konfiguration erfordert jedoch, dass nur eine einzige konkrete Art implementieren, die eine bestimmte version der ILogger<> interface - ansonsten gibt es eine zweideutige situation, die Sie lösen müssen.
Können Sie ausführen möchten, einige interne caching zu vermeiden, die die Kosten der Durchführung Reflexion bei jedem Aufruf von Create().
Ist hier einige Beispiel-code, den Sie könnte beginnen mit.
Hängt davon ab, wie viele Typen, die Sie beabsichtigen, zu behandeln. Wenn es klein ist (weniger als 10), würde ich vorschlagen, eine switch-Anweisung, wie es schnell und Reiniger zu Lesen. Wenn Sie wollen mehr Sie möchten, eine lookup-Tabelle (Hash-Map, Dictionary, etc), oder eine Reflexions-basierten system.
switch-Anweisung vs Wörterbuch - spielt keine Rolle für die perfomance, wie ein Schalter kompiliert in ein Wörterbuch. So wirklich ist es eine Frage der readabilty und Flexibilität. Der Schalter ist einfacher zu Lesen, auf der anderen Seite ein Wörterbuch kann erweitert werden zur Laufzeit.
Könnten Sie die Verwendung eines dependency injection-Frameworks wie hier Einheit. Sie können konfigurieren, dass es mit den generischen Typen, dass Ihr Faktor zurück und das mapping in der Konfiguration. Hier ist ein Beispiel, dass.
1) ich bin immer erstaunt über die Komplexität der Menschen in der Protokollierung. Immer scheint wie overkill zu mir. Wenn log4net ist opensource, ich empfehlen, dass Sie gehen sehen, infact, Sie könnte genauso gut verwenden Sie es ...
2) ich Persönlich versuchen zu vermeiden, Typüberprüfung Wann immer möglich - es Niederlagen der Punkt, der Generika. Verwenden Sie einfach die .ToString () - Methode und mit ihm getan werden.
Hrm... man könnte eigentlich versuchen, ein wenig mehr zu diesem clever, je nachdem, welche der gegebenen Laufzeit-system unterstützt. Ich eigentlich versuchen zu vermeiden, den bedingten Anweisungen in meinem code, wenn ich kann, vor allem in polymorph und dynamisch gebunden-code. Sie haben eine generische Klasse, also warum nicht verwenden es?
Beispielsweise in Java, können Sie vor allem nutzen Sie die statische Methode hast du hier zu tun so etwas wie dieses:
Würden Sie es so nennen:
Dadurch vermieden, dass irgendwelche Bedingungen und flexibler ist außerdem: jede Klasse, die eine Unterklasse (oder implementiert die logger-Schnittstelle, vielleicht) SomeUsefulClass zurückkehren können, die richtig getippt logger-Instanz.