Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!
Werbeanzeige
C#-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class PrintPlugin : IGkPlugin { private List<GkModule> modules; public PrintPlugin() { modules = new List<GkModule>(); modules.Add( new GkPrintOrdersPerDayModule() ); // Das jeweilige Drucker Module } public List<GkModule> Modules { get { return modules; } } public string Author { get { return string.Empty; } } public void Install() { // Nothing to install } public void Remove() { // nothing to delete } } |
C#-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public FinancialControlView( FinanceWorkspace dataContext ) { InitializeComponent(); DataContext = dataContext; // Initialisiert die aktuelle Lokale mit ihren Eigenschaften (€ oder $ ...) this.Language = XmlLanguage.GetLanguage( Thread.CurrentThread.CurrentCulture.Name ); var plugins = GkPluginManager.Current.GetModules<GkFinancialPrinterModule<OrderViewModel>>(); foreach (var plugin in plugins) { plugin.SetContext( dataContext.StartPoint, dataContext.EndPoint, dataContext.OrderCollection ); Button btn = new Button { Content = plugin.Name, Command = new RelayCommand(p => plugin.PrintDocument()), Width = 120, Height = 50, Margin = new Thickness(5) }; wrapPanel.Children.Add( btn ); } } |
Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von »dot« (23.09.2011, 01:18)
Das würde ich eher nicht tun. Reflection ist toll, aber da würde ich an der Stelle zu einer Init-Methode im Interface raten. Wenn du einige an Plugins hast, kann sich das bemerkbar machen, reflection ist halt nicht das fixeste. und ich halte es aus Pluginsicht sauberer. Jeder, der ein Plugin schreibt, weiss, dass die Init der Punkt zum initialisieren ist - das ausführen des "doofen code mit Konstruktor + Init" vollführt die ladende Assembly.Du könntest per Reflection sicherstellen, dass ein entsprechender Konstrutktor vorhanden ist.
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »dot« (23.09.2011, 10:35)
Finde ich persönlich nicht. das macht das erzeugen des Plugins enorm einfach. du musst den Konkreten Typ nicht kennen, sondern nur das Interface. Damit lässt sich ein simpler AssemblyReader entwerfen, der einfach in einem Pluginverzeichnis alle Assemblies abklappert und nach Klassen sucht, die dieses Interface implementieren - da braucht man dann reflection, das lässt sich aber mit FullNames + Timestamps prima cachen. Das macht das Laden von Plugins total easy:Ja ich würde es auch nicht mit Reflection lösen. Aber ehrlich gesagt, fänd ich eine Init() Methode noch sehr viel hässlicher. Macht aber eh nix, denn es gibt ja eine saubere Lösung: Factory.
C#-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
using System;using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; namespace Hyperlinktets { public interface MyPluginInterface { void Init(); } public class PlugInManager { public List Plugins { get; private set; } public PlugInManager(string pluginPath) { Plugins = new List(); string[] files = Directory.GetFiles(pluginPath); foreach (string file in files) { string extension = Path.GetExtension(file); if (extension != null && extension.ToLowerInvariant() == ".dll") { try { Assembly assembly = Assembly.Load(file); IEnumerable myPluginClasses = assembly.GetTypes().Where(t => t.GetInterfaces().Any(i => i is MyPluginInterface)); foreach (var myPluginClass in myPluginClasses) { MyPluginInterface plugin = (MyPluginInterface)assembly.CreateInstance(myPluginClass.FullName); plugin.Init(); Plugins.Add(plugin); } } catch (Exception ex) { Log.Write(string.Format("Could not load assembly: {0}\n Error: {1}"), file, ex.Message); } } } } } } |
Finde ich persönlich nicht. das macht das erzeugen des Plugins enorm einfach. du musst den Konkreten Typ nicht kennen, sondern nur das Interface.Ja ich würde es auch nicht mit Reflection lösen. Aber ehrlich gesagt, fänd ich eine Init() Methode noch sehr viel hässlicher. Macht aber eh nix, denn es gibt ja eine saubere Lösung: Factory.
Das klingt ja schonmal ganz interessant. Das Problem ist nur, dass ja bekannt sein muss, welche Argumente der Factory übergeben werden müssen. Meinst du etwa, dass ich das Factory-Interface in der API definiere? So viel habe ich verstanden:So kann der PluginServer dem PluginManager mitteilen, was für Plugins in der dll stecken und wie sie instanziert werden können (übergibt z.B. eine Factory für das Plugin).
C#-Quelltext |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class PrinterFactory<T> : IGkPluginPrinterFactory { T CreateInstance(IEnumerable<OrderViewModel orders>) {...} } public class PrinterPluginServer : GkPluginServer { ... public void RegisterPlugin(GkPluginManager pm) { pm.AddFactory(IGkPluginPrinterFactory, new PrinterFactory<PrinterModule1>()); pm.AddFactory(IGkPluginPrinterFactory, new PrinterFactory<PrinterModule2>()); .... } .... } |
Meinst du etwa, dass ich das Factory-Interface in der API definiere?
Werbeanzeige