Upload
eevolution-gmbh-co-kg
View
217
Download
1
Embed Size (px)
DESCRIPTION
Pressebericht von dotnetpro.com zum iCustomizer
Citation preview
58 1.2012 www.dotnetpro.de
PRAXIS
Customizing von Standardsoftware leicht gemacht
Software zur Laufzeit anpassenDer Beitrag beschreibt aus Entwicklersicht, welche Möglichkeiten das Produkt iCustomizer bietet, um Software zurLaufzeit zu beeinflussen. Kunden können die Anwendung damit anpassen, ohne in den Sourcecode einzugreifen.
H ersteller von Standardsoftware möch-
ten ihre Kunden zufriedenstellen und
müssen dazu immer wieder Sonder-
wünsche realisieren. Das stellt Softwareentwick-
ler in der ganzenWelt vor die Herausforderung,
eineVielzahl unterschiedlicherVersionen warten
zumüssen.Hierwird aufgezeigt, welcheMöglich-
keitendas Produkt iCustomizer [1] bietet, umden
Programmablauf zur Laufzeit zu beeinflussen.
Kunden oder auchConsultants könnenmit iCus-
tomizer eigeneAnpassungen ander Software vor-
nehmen, ohne dass der Hersteller in den Source-
code der Anwendung eingreifenmuss.
Als Entwickler einer ERP-Standardsoftware
standen wir bei der nGroup vor der Aufgabe,
kundenspezifische Anpassungen aus unserer
Software auszulagern. Ziel war es, die Standard-
software von individuellem Code zu befreien,
umbei der Release-Planung und -Durchführung
keine Rücksicht auf spezielle Kundenversionen
nehmen zumüssen.Wir haben zu diesemZweck
den iCustomizer entwickelt: um unseren Part-
nern und Kunden Einflussmöglichkeiten zu ge-
ben und sie Funktionen erstellen zu lassen, die
wir als Entwickler nicht vorgesehen haben.
Der iCustomizer besteht aus zweiTeilen, einem
Designer und einem Skripteditor. In die eigene
Anwendungmuss nur wenig Quelltext eingebaut
werden, damit die Applikation zur Laufzeit den
kundenindividuellen Code ausführen kann.
Designer und SkripteditorDerDesigner ist einWerkzeug,mit demGUI-Ele-
mente und Control-Eigenschaften bearbeitet
oder neue Controls hinzugefügt werden (Abbil-
dung 1).Wie aus Entwicklungsumgebungen be-
kannt, stehen dabei Hilfslinien zur Ausrichtung
vonControls, eineToolbox für neueControls und
ein PropertyGrid zum Editieren der Eigenschaf-
ten zurVerfügung. An Controls können grafische
Anpassungen vorgenommen werden. So kann
beispielsweise die Position von Feldern und But-
tons, die Textfarbe oder Ähnliches den eigenen
Wünschen angepasstwerden. Bei der Implemen-
tierung wurden die Klassen DesignSurface und
DesignerHost aus dem Namensraum System.
ComponentModel.Design verwendet, sodass der
gleiche Designmechanismus wie inVisual Studio
genutzt wird. Es können neue Controls hinzuge-
fügt sowie vorhandene Controls um neue Funk-
tionen erweitert werden, die ursprünglich nicht
vorgesehen waren. Das geschieht über die Defi-
nition von Eventhandlern.
Der Code wird mit dem Skripteditor geschrie-
ben (Abbildung 2). Im Skripteditor wird man
beim Programmieren unterstützt durch Auto-
Auf einen Blick
Marco Spilker ist Software-entwickler bei der nGroup inHildesheim. Er ist für die Archi-tektur der betriebswirtschaftli-chen Software verantwortlich,berät in technologischen Fragenund dient als Anlaufstelle iminternen Support. Der studierteRechtswissenschaftler konver-tierte zur Jahrtausendwendezum Informatiker und machtedamit seine Leidenschaft zumBeruf. Marco widmet sich seit2003 der .NET-Programmierung.
Inhalt� Vorstellung des Tools iCusto-mizer.
� Wie man den iCustomizer ineigenen Anwendungen nutzt.
� Wie Kunden das Produkteinsetzen.
A1201iCustomizer
dnpCode
Um iCustomizer in ein eigenes Windows-Forms-Projekt integrieren zu können, müssen folgendeVorarbeiten erledigt werden :� EinenVerweis auf dieAssembly nGroup.FormCusto-mizer.dll hinzufügen.
� Die Lizenzdatei nGroup.FormCustomizer.licx demProjekt als eingebettete Ressource hinzufügen. Da-durch wird beim Erstellen des Projekts der LicenseCompiler lc.exe ausgeführt und die Lizenz wird in dieAnwendung eingebettet. Beim Kunden sind keineweiteren Lizenzen bereitzustellen.
� Die Konfigurationsdatei nGroup.FormCustomizer.dll.settings.config zum Projekt hinzufügen und dieOption In Ausgabeverzeichnis kopieren aktivieren,dar-über hinaus in der app.config-Datei den AbschnittnGroup.FormCustomizer.Properties.Settings eintragen.
� In der Konfigurationsdatei kann ein Hotkey für denAufruf des Bearbeitungsmodus des iCustomizersfestgelegt oder deaktiviert werden.Außerdem kanndort dasVerzeichnis angegeben werden, in dem dieDateien mit den Benutzeranpassungen gespeichertwerden. Beide Mechanismen lassen sich auch imCode anpassen oder komplett überschreiben.
Die Integration vorbereiten
Hersteller einer Software können den Designer desiCustomizers konfigurieren und so festlegen, welcheMöglichkeiten sie ihren Kunden einräumen wollen.� Es können die Änderungen an einzelnen Eigen-schaften (Properties) von Steuerelementtypen ge-zielt erlaubt oder verboten werden.
� Der Designmodus für einzelne Controls oder Typenvon Controls kann geändert oder gesperrt werden.
� Die Toolbox kann mit formularspezifischen Elemen-ten gefüllt werden.
� Events können formularspezifisch benutzt werden.� Die Speicherstreams für das Laden und Speichernder Customizings können umgeleitet werden.
� Dem Benutzer kann das Editieren von Skripten er-laubt oder verboten werden.
Den Designer anpassen
058dnp_iCustomizer_ws_la_ws_cg_sb_ws.qxp:Layout 1 23.11.2011 17:15 Uhr Seite 58
Created for Tilman Börner ([email protected]) - 2533 on 12.03.2012 17:12:35Please do not make illegal copies!
www.dotnetpro.de 1.2012 59
PRAXIS
vervollständigung, Auswahlfelder mögli-
cher Funktionen und farbliche Hervor-
hebung, sodass diese Arbeit leicht von der
Hand geht.
Zur Ausführungszeit werden die ge-
schriebenen Skripte dynamisch kompiliert.
Dabei kommt die C#-Version des System.
CodeDom.Compiler.CodeDomProvider zum
Einsatz. Damit stehen die gesamteC#-Syn-
tax und der vollständige Funktionsumfang
von .NET zurVerfügung.
Im Skripteditor lassen sich auch eigene
Assemblies oder solche vonDrittherstellern
laden und integrieren, die dann mit dem
Skriptcode, den Controls oder den Events
verknüpft werden können. Auf dieseWeise
ist quasi jede Anwendung integrierbar und
der Skriptcodedient als Anknüpfungspunkt
für die gesamte .NET-Infrastruktur.
Nach dem Starten des Designers steht ein
PropertyGrid zur Verfügung, mit dem man
die Eigenschaften der Controls und die
Events derControls verändernkann.Als Ent-
wickler beimHersteller könnenSie festlegen,
welche Änderungsmöglichkeiten Sie Ihren
Kunden erlauben möchten (siehe Kasten
Den Designer anpassen). Es gibt die zwei
Grundeinstellungen–„alles erlaubt“und„al-
les verboten“ –unddarüberhinaus individu-
elle Einschränkungsmöglichkeiten für jedes
Control und jeden Event. So lässt sich bei-
spielsweise konfigurieren, dass alles erlaubt
ist außer dem Zugriff auf ein Textfeld eines
bestimmten Controls. Ein Beispiel für die
Konfigurationsmöglichkeiten zeigt Listing 1.
iCustomizer integrierenMitwenigenCodezeilen lässt sich der iCus-
tomizer in eigene Produkte integrieren. Zu-
nächst sind einigeVorbereitungennotwen-
dig, die Sie im Kasten Die Integration vor-
bereiten nachlesen können. Danach lässt
sich der iCustomizer mit der festgelegten
Tastenkombination in der eigenenAnwen-
dung aufrufen.
Man kann sich den iCustomizer als Ver-
längerung desWindows-Forms-Designers
von Visual Studio in die Laufzeit der Soft-
ware hinein vorstellen. Daher muss er zu
einem möglichst frühen Zeitpunkt an die
Form angehängt werden.
Die Einstellungen desWindows-Forms-
Designers werden ganz am Anfang des
Lebenszyklus getroffen, indem im Kon-
struktor der Form die vom Windows-
Forms-Designer erzeugte Methode Initia-
lizeComponent aufgerufenwird. Nach dem
Ausführen dieser Methode befindet sich
die Form in dem Zustand, der zur De-
signzeit im Designer festgelegt wurde.
Danach werden gegebenenfalls vom Ent-
wickler noch weitere Initialisierungen im
Konstruktor programmiert oder aus dem
Code heraus Eigenschaften der Form ge-
setzt, bevor diese angezeigt wird.
Den iCustomizer mit WindowsForms verknüpfenDas nächste Ereignis im Lebenszyklus der
Form ist der Event HandleCreated bezie-
hungsweise das Ausführen der Methode
OnHandleCreated. Dieses stellt einen ge-
[Abb. 1] Im Designer
entwickelt man alle
kundenspezifischen
Anpassungen der
Benutzeroberfläche.
[Abb. 2] Der Entwickler
wird beim Programmie-
ren durch Auswahlfelder
unterstützt.
058dnp_iCustomizer_ws_la_ws_cg_sb_ws.qxp:Layout 1 23.11.2011 17:15 Uhr Seite 59
Created for Tilman Börner ([email protected]) - 2533 on 12.03.2012 17:12:35Please do not make illegal copies!
60 1.2012 www.dotnetpro.de
PRAXIS _Customizing von Standardsoftware leicht gemacht
/// <summary>/// Is triggered whenever a Form is being set into the design mode, and once for each Control./// Can be used to change the design mode for specific Controls (see MainWindow.CustomizerChangeComponentDesignMode)./// In this demo the event is also directed to the currently active Form and CustomizerChangeComponentDesignMode does nothing./// </summary>/// <param name="sender">The source of the event.</param>/// <param name="args">The <see cref="nGroup.FormCustomizer.GetComponentDesignModeEventArgs"/> instance containing the event data.</param>public static void CustomizerChangeComponentDesignMode(object sender, GetComponentDesignModeEventArgs args){// Since we are setting the event in CustomizerActivating to trigger CustomizerChangeComponentDesignMode on the Form, there is no code here.// If there was a type of Control to never be customizable at all, this would be a nice place to declare it.////if (args.Component is *ControlType*) args.DesignMode = ComponentDesignModes.None;
}
/// <summary>/// Disable specific properties for types of Controls./// </summary>private static void ConfigureDisablePropertySettings(){// The Text property of a textbox should not be changeable in the Customizer, since it is set by business logic.Customizer.ControlDefaultDisableProperties.Set(typeof(TextBox), "Text", DisablePropertySetting.Disable);
// Enabled is also not allowed to be changed, because it could prevent from important buttons being pressed.Customizer.ControlDefaultDisableProperties.Set(typeof(Control), "Enabled", DisablePropertySetting.Disable);
// By default everything is allowed to be changed. Above is the command to disable specific properties.// You can also change the default by setting it to DisablePropertySetting.Disable.// Now ALL properties are not allowed to be changed.// Only properties allowed by setting DisablePropertySetting. Enable will be allowed to be changed.////Customizer.ControlDefaultDisableProperties.Default = DisablePropertySetting.Disable;////Customizer.ControlDefaultDisableProperties.Set(typeof(*ControlType*),//// "*PropertyName*", nGroup.FormCustomizer.DisablePropertySetting.Enable);
}
/// <summary>/// Sets what kind of customization the user is allowed to do./// </summary>/// <param name="allowCustomizingForUser">Allow starting the customizer and doing UI changes.</param>/// <param name="allowScriptingForUser">Allow scripting.</param>public static void SetCustomizerAvailability(bool allowCustomizingForUser, bool allowScriptingForUser){// Note: If EnableDesignerForUser is false while attaching a new Form the customization will be loaded in show-only mode, which is faster.// The user will not be able to change this forms customization even if the EnableDesignerForUser value changes.// Only when the Form is created while EnableDesignerForUser is true it will be possible to customize.Customizer.EnableCodeEditorForUser = allowScriptingForUser;Customizer.EnableDesignerForUser = allowCustomizingForUser;
}
/// <summary>/// Adds a collection of Controls to the Toolbox./// The Controls can then be placed on a Form in design mode./// </summary>private static void AddToolboxItems(){Customizer.AddToolboxItem(typeof(Button), "Controls", "Buttons", true);Customizer.AddToolboxItem(typeof(TextBox), "Controls", "Textboxes", true);Customizer.AddToolboxItem(typeof(Label), "Controls", "Textboxes", true);Customizer.AddToolboxItem(typeof(CheckBox), "Controls", "Buttons", true);Customizer.AddToolboxItem(typeof(RadioButton), "Controls", "Buttons", true);Customizer.AddToolboxItem(typeof(GroupBox), "Container", "Groupings", true);Customizer.AddToolboxItem(typeof(Panel), "Container", "Groupings", true);Customizer.AddToolboxItem(typeof(SplitContainer), "Container", "Groupings", true);Customizer.AddToolboxItem(typeof(DataGrid), "Container", "TableViews", true);
}
Konfigurieren des Designers.
Listing 1
058dnp_iCustomizer_ws_la_ws_cg_sb_ws.qxp:Layout 1 23.11.2011 17:15 Uhr Seite 60
Created for Tilman Börner ([email protected]) - 2533 on 12.03.2012 17:12:35Please do not make illegal copies!
PRAXIS
eigneten Zeitpunkt für das Anhängen des
iCustomizers dar: Alle Designzeit-Einstel-
lungen sind getroffen, aber die Form wird
noch nicht angezeigt.
Üblicherweise sollen alle Forms oder
ausgewählten Forms einer Anwendung für
das Customizing zurVerfügung stehen.Da-
mit der Code nicht jeder Form individuell
angepasst werden muss, bietet es sich an,
OnHandleCreated in einer gemeinsamen
Basisklasse aller anpassbaren Forms zu
überschreiben. So kann etwa ein statisches
Event FormCreating erstellt werden, wel-
ches das Erzeugen neuer Forms an einem
zentralen Punkt überwacht (Listing 2).
Als Alternative zur Basisklasse stellt der
iCustomizer die Klasse FormCreationObser-
ver bereit (Listing 3).
Diese Klasse erlaubt es, über einen loka-
len Windows Hook [2] die gesamte An-
wendung auf das Versenden der Fenster-
nachrichtWM_CREATE zu überwachen. So
kann für alle Forms der Anwendung ein
FormCreating-Ereignis bereitgestellt wer-
den, ohne etwas an den Forms der Anwen-
dung zu verändern.
Wird man auf die eine oder andere Art
undWeise über die Erstellung einer neuenpublic static event EventHandlerFormCreating;
protected override voidOnHandleCreated(EventArgs e) {if (!this.RecreatingHandle){EventHandler formCreating =FormCreating;
if (formCreating != null){formCreating(this, e);
}}
base.OnHandleCreated(e);}
Eventhandler FormCreating.
Listing 2
FormCreationObserver formCreationObserver = new FormCreationObserver();formCreationObserver.FormCreating += FormCreating;formCreationObserver.StartObserving();
FormCreationObserver.
Listing 3
public static void FormCreating(object sender, EventArgs e)
{Form form = sender as Form;Customizer.Attach(form);[…]
}
Customizer.Attach.
Listing 4
058dnp_iCustomizer_ws_la_ws_cg_sb_ws.qxp:Layout 1 23.11.2011 17:15 Uhr Seite 61
Created for Tilman Börner ([email protected]) - 2533 on 12.03.2012 17:12:35Please do not make illegal copies!
62 1.2012 www.dotnetpro.de
PRAXIS _Customizing von Standardsoftware leicht gemacht
Form benachrichtigt, so kann nun der
iCustomizer im Eventhandler an die Form
angehängt werden. Dazu muss die stati-
sche Methode Customizer.Attach aufgeru-
fen werden (Listing 4). Der iCustomizer
merkt sich nun alle Eigenschaften der
Form, indem er rekursiv über alle Controls
iteriert und den Zustand der Property-De-
skriptoren speichert. Werden später der
iCustomizing-Modus aktiviert und der De-
signer gestartet, kann damit die Form in
diesen Zustand zurückversetzt und die Än-
derungen können im Designer als Diffe-
renz (Customizing) abgespeichert werden.
Dieser Schritt ist also nur notwendig,
wenn später ein Customizing der Form
durchgeführt werden soll. Dieses lässt sich
über die Eigenschaft EnableDesignerFor-
User deaktivieren.
Laden von CustomizingsNachdem sich der iCustomizer den Ur-
sprungszustand der Form gemerkt hat,
sucht er basierend auf dem Typnamen der
Form nach einem vorher gespeicherten
Customizing. Dabei wird standardmäßig
im Dateisystem gesucht. Der Ladevorgang
lässt sich aber überschreiben und anpas-
sen, indemeinDelegat für die Ladefunktio-
nalität angegeben wird. Umgekehrt kann
auch einDelegat für das Speichern angege-
benwerden.DieDelegatmethodenmüssen
folgende Signaturen tragen:
Stream LoadCustomization(string customizingName);
void SaveCustomization(string customizingName, Stream s);
Wurde vom iCustomizer einCustomizing
für die eben geladene Form gefunden, so
wird es imnächstenSchritt auf die Forman-
gewendet. Dabei werden die im Customi-
zing gespeicherten Eigenschaften gesetzt,
die Skripte kompiliert und als Eventhandler
mit den entsprechenden Events der Form
und der Controls verbunden.
Starten des DesignersDanach wird die Form normal geladen. Es
kann nun jederzeit der Designmodus des
iCustomizers aktiviert werden. Dazu muss
dieMethodeCustomizer.ActivateCustomizer
aufgerufenwerden. Standard ist, dass dieser
Aufrufmit demHotkey [Strg]+[F8] verknüpft
ist. Dazu enthält der iCustomizer die Klasse
HotKeyWatch,mit der sich beliebige anwen-
dungsweiteHotkeys erstellen lassen.
HotKey hotKeyActivateCustomizer =new HotKey("Control.F8");
HotKeyWatch.RegisterHotKey(hotKeyActivateCustomizer,Customizer.ActivateCustomizer);
Beim Start des Designers wird der Ur-
zustand der Form wiederhergestellt, der
beimAnhängen des iCustomizers inCusto-
mizer.Attach gespeichert wurde. Dannwird
der Designer angezeigt und Form sowie
Skripteditor stehen zur Bearbeitung bereit.
Speichern des CustomizingsNach dem Bearbeiten der Form und der
Skripte wird das Customizing beim Schlie-
ßen des Designers gespeichert. Wie beim
Ladenkannauchhier eine eigene Speicher-
funktionalität verwendetwerden.Der iCus-
tomizer ermittelt dieUnterschiede zumUr-
sprungszustand und schreibt diese Diffe-
renz als XML in den Speicherstream. Das
gespeicherte Customizing enthält dabei In-
formationen über neu hinzugefügte Con-
trols, die Hierarchie der Controls, die geän-
derten Eigenschaften der Controls, den
Scripting-Code sowie die Eventbindungen.
Neustart der FormAnschließend wird der Designer beendet.
Die vorgenommenen Änderungen und
Skripte sind nun sofort aktiv. Allerdings
könnte der Gesamtstatus der Form nicht
mehr dem Zeitpunkt entsprechen, zu dem
derDesigner gestartet wurde. ZumBeispiel
könnte der Benutzer den Status durch In-
teraktion mit der Form bereits verändert
haben, bevor derDesigner gestartet wurde.
Versteht man den iCustomizer als Ver-
längerung des Windows-Forms-Designers
und der InitializeComponent-Methode, so
könnte der Programmierer im normalen
Ablauf des Ladens der Form weitere Ände-
rungen des Status vorgenommen haben,
die sich jetzt nicht in der genau richtigen
Abfolge wiederholen lassen. Die Form
könnte sich also insgesamt in einem inkon-
sistentenZustandbefinden.Daher sollte die
bearbeitete Form nach dem Customizing
geschlossen undwieder geöffnet werden.
PraxisbeispieleUnsere Kunden und Partner nutzen die
neuen Möglichkeiten des iCustomizers
gern und vielfältig. Sehr häufig werden
Masken übersichtlicher gemacht undnicht
benötigte Eingabe- oder Ausgabefelder
ausgeblendet. Mit neuen Reitern werden
eigeneÜbersichtsseiten erstellt und die In-
formationen von verschiedenen Stellen der
Applikation aufbereitet. Mit neuen Con-
trols werden eigene Funktionalitäten ein-
gebaut. So wurde mit einem zusätzlichen
Schnellsuchfeld dasDurchsuchen von gro-
ßen Tabellen erleichtert: Alle Zeilen, die
mit dem dort eingegebenen Suchbegriff
übereinstimmen, werden farbig markiert.
Auch Browserfenster werden häufig in die
Applikation integriert: Diese lassen sich
aufrufen und innerhalb der Applikation
bedienen. Damit werden Informationen
übergeben, um Lieferanten- oder Kunden-
Internetseiten (Artikel, Adressen) sofort
einzublenden.
Auch für Plausibilitätsprüfungen bei der
Eingabe wird der iCustomizer verwendet:
Hier werden zumTeil komplexe Prüfungen
durchgeführt und Artikelkennzeichen mit
Datenbankeinträgen verglichen, bevor sie
gespeichert werden. Dadurch lässt sich die
Datenqualität verbessern. Alle Beispiele
wurden realisiert, ohne amProgrammcode
der Standardanwendung irgendetwas Indi-
viduelles für einen Kunden zu entwickeln.
iCustomizer als Beratungs-werkzeugEinige Hersteller von Standardsoftware, die
den iCustomizer in ihre Produkte integriert
haben, nutzen ihn als Beratungswerkzeug:
In der Einführungsphasewerden alleModi-
fikationswünsche des Kunden gesammelt.
Nach der Einführung bespricht man diese
mit dem Kunden und gemeinsam mit ihm
wird entschieden, was angepasst werden
soll. Sowerden hauptsächlichMasken opti-
miert und Eingaben validiert, ohne dabei
denQuellcode verändern zumüssen.
Änderungen werden dabei nicht vor Ort
imKundensystemvorgenommen, sondern
in Ruhe entwickelt und getestet und dann
beim Kunden eingespielt. Die kundenspe-
zifischen Anpassungen bleiben auch bei
Updates funktionsfähig, können individu-
ell gewartet werden und beeinflussen die
Release-Zyklen nicht.
FazitMit Werkzeugen wie dem iCustomizer ist
esmöglich, Kunden undPartnern eine gro-
ße Flexibilität bei der Anpassung von Stan-
dardsoftware an die eigenen Bedürfnisse
zu erlauben. Gleichzeitig behält man als
Hersteller die Kontrolle über den Pro-
grammcode und vereinfacht das Release-
Management, weil Sonderentwicklungen
außerhalb des Produkts durchgeführt wer-
den können. [bl]
[1] iCustomizer, www.nGroup.info/iCustomizer[2] Lokaler Windows Hook,
www.dotnetpro.de/SL1201iCustomizer1
058dnp_iCustomizer_ws_la_ws_cg_sb_ws.qxp:Layout 1 23.11.2011 17:15 Uhr Seite 62
Created for Tilman Börner ([email protected]) - 2533 on 12.03.2012 17:12:35Please do not make illegal copies!