Instanziieren alle Klassen implementieren eine bestimmte Schnittstelle
Habe ich eine Schnittstelle IExample
, und eine Reihe von Klassen ClassOne
, ClassTwo
und ClassThree
alle definierten in verschiedenen namespaces. Werde ich eventuell entfernen, die entweder von den Klassen, oder einen neuen hinzufügen, in einem neuen Ort, in einem späteren Stadium der Entwicklung.
Nun, ich will finden Sie alle Arten implementieren IExample
zur Laufzeit, und instanziieren Sie. (Ich weiß vorher, dass keine Klasse die IExample
je brauchen wird jeder Konstruktor Argumente, aber ich weiß nicht, wie Sie angeben, dass Sie im code, so ist es mir - nicht der compiler, der weiß, dass...)
Ist das möglich? Wie gehe ich vor, es zu tun?
Update: ich habe jetzt versucht, mehrere Ansätze vorgeschlagen, aber auf allen von Ihnen, die Linie Activator.CreateInstance(type)
, bekomme ich eine System.MissingMethodException, weil ich "nicht erstellen Sie eine Instanz der Schnittstelle." Das ist mein code:
var tasks = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes())
.Where(t => typeof(IBootstrapperTask).IsAssignableFrom(t))
//This line is where it fails
.Select(t => Activator.CreateInstance(t) as IBootstrapperTask)
.ToArray();
new AutoMapperBootstrapper(tasks).Initialize();
Ohne die as
Klausel sehe ich keine Ausnahme, aber ich bin angesichts einer object[]
, und ich brauche eine IBootstrapperTask[]
für den Konstruktor auf die Letzte Zeile in den Auszug. Ich habe versucht, verschiedene Möglichkeiten, um Sie zu wirken, aber keiner scheint zu funktionieren.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Diese kann getan werden, mit Reflexion. Zum Beispiel
Hinweis: Dies wird nur Instanzen von
IExample
von Baugruppen geladen, die in der aktuellenAppDomain
. Diese können, anders als alle assemblies geladen, der im aktuellen Prozess. Doch für viele Arten von Anwendungen dieser Maßnahme.Müssten Sie wissen, eine Liste der Assemblys zu suchen, dann aber LINQ ist es relativ einfach:
Können Sie denken, dass einige andere Einschränkungen hinzufügen, aber Sie sind ziemlich einfach auszudrücken 🙂
instances
wird dann eineList<IExample>
.EDIT: ich vermute meine code funktioniert dort, wo Ihnen nicht, denn ich bin speziell ohne non-Klassen. Meine Vermutung ist, dass Sie Ihren code zu instanziieren versucht, das interface selbst, d.h. wenn
t
isttypeof(IBootstrapperTask)
.ToArray
wenn Sie wollen.) Zugegeben, ich kann nicht sehen, warum dieas
irgendeinen Unterschied gemacht hätte, zu Ihrem ursprünglichen code...Benötigen Sie dieses, um zu geschehen dynamisch? Gibt es immer mal, wenn man vielleicht eine, die Sie nicht wollen, zu schaffen? Mir scheint, dass dies ist ein gutes Beispiel für dependency injection (kann konfiguriert werden). Zum Beispiel hat die Einheit einer ResolveAll Methode .
Aus dem oben genannten link;
Versuchen, mithilfe von reflektion, um die Arten der Umsetzung
IExample
. Dieses Beispiel sieht an der aktuellen Versammlung, doch Sie könnte leicht passieren eine andere Baugruppe:Contains
? Auch, dass nicht Vererbung behandeln.t.GetInterfaces()
auf den Typen. Ich benutze etwas ähnliches in einem Projekt von mir.