Ich habe eine Situation, in der ich eine Plugin-Architektur in meiner Klassenbibliothek freigegeben habe, und ich möchte, dass andere die von mir erstellten Schnittstellen implementieren und ihre benutzerdefinierten Implementierungen von der Klasse verwenden können.
Ich verwende Dependency Injection (speziell Konstruktorinjektion), um dies zu erreichen.
Dies funktioniert gut, abgesehen davon, dass ich versucht habe, die Anwendung mit zwei sich widersprechenden Zielen zu entwerfen:
- Die Benutzer der API sollten die Rückgabewerte nicht ändern können; Ich habe benutzerdefinierte schreibgeschützte Sammlungen und Objekte erstellt, indem ich
internal
auf die Setter und ähnliche verwendet habe, um sicherzustellen, dass keine Benutzer sie ändern können - Plugins in anderen Assemblys sollten auf diese internen Methoden und Eigenschaften zugreifen können
Diese beiden Ziele widersprechen sich, da es keine Möglichkeit gibt, dass meine API (oder C#) den Zugriff auf internal
(über InternalsVisibleTo
oder ähnliches) für die Plugin-Assemblys gewährt, aber nicht für allgemeine Benutzer.
Veranschaulichendes Beispiel
Angenommen, wir haben drei Assemblys. Meine Klasse (Klasse
), eine Plugin-Assembly (Plugin
) und eine Verbraucher-Assembly (Verbraucher
).
Ein Interface, IReturnValue
spezifiziert einen Rückgabewert der API (eine Methode oder Klasse in der Assembly Klasse
). Das Problem ist folgendes: Ich möchte, dass Plugin
schreibgeschützte (internal
) Eigenschaften und Indexer an einer beliebigen Instanz von IReturnValue
festlegen kann, möchte aber nicht, dass der Code von Verbraucher
dies tun kann.
Da ein Plugin-System verwendet wird, kann ich im Voraus nicht wissen, welchen Assemblys InternalsVisibleTo
gewährt werden soll.
In dieser Situation sollte es mich wirklich interessieren, ob Verbraucher die Rückgabetypen ändern? Es scheint mir, dass es ihr eigenes Verschulden ist, wenn sie dies tun. Und ich kann mir keine vernünftige Lösung für dieses Problem einfallen lassen.