Es gibt eine Anwendung A, welche eine Form instantiiert und desweiteren ein Plugin, dynamisch zur Laufzeit lädt, welches ein Interface implementiert.
Ich befinde mich im Scope des Plugins und kenne erstmal nicht die Elternanwendung und habe keine Referenzen darauf bei der Erzeugung des Plugins.
Also sprich kein new MeinPlugin(this);
Das Plugin kennt also seinen Kontext nicht.
Mein Problem an dieser Stelle: Ich benötige diesen Kontext.
Gibt es einen Weg aus dem Plugin (DLL) die Form der Anwendung A zu bekommen?
Vom Konzept her ist es unsauber, dessen bin ich mir bewusst. Ich versuche nur zu prüfen, ob ich über Reflection an die aktuelle Instanz rankomme oder nicht.
Die Typinformation von der Form da oben habe ich bereits durch das Einbinden der Anwendung A Assembly, ich finde nur keinen Weg, mir die Instanz zu holen.
Ich krieg über Reflection den Stack und die Methode, aber nicht die Instanz selbst, hmmm
Life is a short
Ja, das ist möglich:
Wir implementieren einen Singleton-Pattern im Formular:
#region singleton implementation
private static volatile F_Plugins instance;
private static object syncRoot = new Object();
public static F_Plugins Instance
{
get
{
if (instance == null || instance.IsDisposed)
{
lock (syncRoot)
{
if (instance == null || instance.IsDisposed)
instance = new F_Plugins();
}
}
return instance;
}
}
#endregion
Im "Plugin" sagen wir nun:
Assembly lEntryAssembly = Assembly.GetEntryAssembly();
Type[] lExportedTypes = lEntryAssembly.GetExportedTypes();
foreach (Type lType in lExportedTypes)
{
if (lType.Name == "F_Plugins")
{
Form lForm = (Form)lType.GetProperty("Instance").GetValue(lType, null);
lForm.Text = "Test123";
break;
}
}
Ich habe mir die Lösung gerade erst ausgedacht da ich sowas sicherlich auch mal bracuhen werde. Es ist unsauber an vielen stellen und wenn man damit richtig arbeiten möchte gibt es sicherlich noch optimierungsbedarf (ggf über ein eigenes Interface für "F_Plugin") dann kann man sich den weg über Reflection sparen.
Funktionieren tut es - gross getestet habe ich es aber nicht.
Ich weis nicht ob man Forms einen Singleton-Pattern reindrücken "sollte" ich finde es aber in vielen fällen einfach praktisch wenn man das Formular sowiso nur maximal 1x benutzen möchte.
Weitere Informationen zu Singleton-Patterns findest du hier:
http://en.wikipedia.org/wiki/Singleton_pattern#C.23
HAI
CAN HAS STDIO?
PLZ OPEN FILE "LOLCATS.TXT"?
AWSUM THX
VISIBLE FILE
O NOES
INVISIBLE "ERROR!"
KTHXBYE
Hallo Seikilos,
Process.GetCurrentProcess ().MainWindowHandle
herbivore
Wenn du nur mit dem Hauptformular arbeiten möchtest funktioniert das auch 😉
Form lTestForm = (Form)Control.FromHandle(Process.GetCurrentProcess().MainWindowHandle);
auch gerade ausprobiert 😉
HAI
CAN HAS STDIO?
PLZ OPEN FILE "LOLCATS.TXT"?
AWSUM THX
VISIBLE FILE
O NOES
INVISIBLE "ERROR!"
KTHXBYE
Process.GetCurrentProcess ().MainWindowHandle liefert mir null.
Das habe ich bereits probiert. Aber wenn ihr das auch vorschlagt, dann sollte es wohl nicht null, oder?
Das Singleton von Myth erfordert die Anpassung des Host codes, was hier ja nicht möglich ist.
Danke
Life is a short
Hallo Seikilos,
es ist nicht sichergestellt, dass eine Anwendung auch ein Hauptfenster hat. Da sind wird dann wieder bei: "Vom Konzept her ist es unsauber". Man kann halt keine verlässliche Aussagen über eine undefinierte Umgebung machen.
herbivore
Ich denke das Problem bei mir ist, dass die Form die Plugins im new von sich selbst lädt. Sprich das Plugin ist da bevor die Form bereit ist. Hmmmf.
Danke für die Hilfe
Life is a short
kann das plugin nicht ein Event werfen, welches im A.Mainwindow verarbeitet wird?
Der frühe Apfel fängt den Wurm.
Nö. Auf A habe ich kein Zugriff, aber A wirft andere Events, an die ich mich probehalber anhängen kann, dann ist der Ctor der Form schon durch und ist verfügbar
Life is a short
Was eventuell interessant wäre: Ist es möglich per Reflection eine Methode aus einer anderen Assembly zu überladen oder sich da reinzuhängen?
Die Hauptanwendung hat update routinen, die keine Events oder etwas in der Art feuern, wenn sie beendet worden sind. Ich muss aber nach dem Update zusätzliche Operationen ausführen, die immer nach dem Update ausgeführt werden müssen.
Problem ist: Mein Plugin kriegt nicht mit, wann das Update durchgeführt worden ist
Life is a short
Hallo Seikilos,
ich muss aber nach dem Update zusätzliche Operationen ausführen
Problem ist: Mein Plugin kriegt nicht mit, wann das Update durchgeführt worden ist
womit wir wieder beim Design wären. Wenn es notwendig ist, dass Plugins nach dem Update informiert werden, dann sollte die Hostanwendung die Plugins informieren.
herbivore
Jepp, keine Frage.
Das wird durchaus auch passieren.
Aber aktuell ist es noch nicht passiert und der Host kann im Moment nicht geändert werden.
Das soll auch kein Produktivcode werden, sondern eher ein Proof of Concept des Plugins.
Die Leute, die sich das angucken, verstehen nichts von Callbacks oder ähnlichem, sondern brauchen quasi ne visuelle Demo
Life is a short