Peter Bucher Ralf Westphal

Blog

Nutze den Augenblick
und teile der Welt mit, was Du zu sagen hast.

Basta! 2009: Clientsicherheit – eine Utopie?

Donnerstag, 24. September 2009, 17:43 Uhr
Permalink | Kommentare (0) | Kommentare als RSSRSS

In Mainz fand diese Woche die Basta! 2009 statt, auf der ich am Mittwoch wieder mit einer eigenen Session vertreten war.

Das Thema meiner Session war Clientsicherheit – eine Utopie?. Grundsätzlich ging es dabei um die Frage, ob Clientsicherheit überhaupt ein erreichbares Ziel ist, oder eben eine unerreichbare Utopie. Außerdem habe ich die Frage diskutiert, warum in verteilten Anwendungen der Fokus in Bezug auf Sicherheit in der Regel auf dem Server liegt.

Vor knapp 20 Teilnehmern habe ich also folgende Themen behandelt:

  • Werkzeuge für Angreifer: ildasm, Reflector, …
  • Sinn und Unsinn von Obfuskatoren
  • Verwendung von digitale Signaturen
  • Einsatz von Zertifikaten
  • Symmetrische und asymmetrische Verschlüsselung

Ergänzt wurden diese Themen durch eine Livevorführung, wie die Sicherheitsmechanismen des GAC von .NET ausgehebelt werden können. Insbesondere das Aushebeln der vermeintlichen Sicherheit auf Basis von Strong Names sorgte für Aufsehen.

Abschließend möchte ich mich an dieser Stelle noch einmal bei den Teilnehmern für die Aufmerksamkeit und die interessanten Fragen bedanken, und hoffe, dass für jeden neue und hilfreiche Anregungen enthalten waren.

Transaktionale Methoden

Sonntag, 6. September 2009, 21:34 Uhr
Permalink | Kommentare (3) | Kommentare als RSSRSS

Spätestens seit dem in .NET 2.0 eingeführten Namensraum System.Transactions ist es keine Kunst mehr, so wohl lokale wie auch verteilte Transaktionen in eigenem Code zu nutzen.

Allerdings ist es dafür in jeder Methode erneut notwendig, einen TransactionScope zu öffnen, gegebenenfalls dessen Complete-Methode aufzurufen und ihn schließlich wieder korrekt zu verwerfen – zumindest dies kann durch den Einsatz einer using-Anweisung erleichtert werden.

Andere Plattformen als .NET bieten an dieser Stelle mehr: So genügt beispielsweise bei der Java Enterprise Edition (JEE) seit dem EJB 3.0-Standard die Angabe der Annotation @TransactionAttribute bei der Deklaration einer Methode, um diese in einer Transaktion auszuführen.

Mit Hilfe von PostSharp ist es jedoch auch innerhalb von .NET ein Leichtes, ein solches Attribut zu entwickeln. Dazu muss lediglich ein OnMethodBoundary-Aspekt geschrieben werden, der beim Aufruf einer Methode einen neuen TransactionScope anlegt, diesen an die Methode bindet, und der beim Beenden der Methode den TransactionScope wieder schließt.

Die Entscheidung, ob ein Commit oder ein Rollback durchgeführt werden soll, kann dann beispielsweise an Hand der Tatsache entschieden werden, ob die gekapselte Methode durch eine Ausnahme oder auf normalem Wege verlassen wurde:

using PostSharp.Laos;
using System;
using System.Transactions;
namespace goloroden.de.Aspects
{
    /// <summary>
    /// Provides transaction control to methods.
    /// </summary>
    [Serializable]
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple = true)]
    public sealed class TransactionalAttribute : OnMethodBoundaryAspect
    {
        /// <summary>
        /// Contains the transaction scope options.
        /// </summary>
        private TransactionScopeOption _transactionScopeOption;
        /// <summary>
        /// Initializes a new instance of the <see cref="TransactionalAttribute" /> type.
        /// </summary>
        public TransactionalAttribute() : this(TransactionScopeOption.Required)
        {
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TransactionalAttribute" /> type.
        /// </summary>
        /// <param name="transactionScopeOption">The transaction scope options.</param>
        public TransactionalAttribute(TransactionScopeOption transactionScopeOption)
        {
            this._transactionScopeOption = transactionScopeOption;
        }
        /// <summary>
        /// Executed when a method is entered.
        /// </summary>
        /// <param name="eventArgs">The event args.</param>
        public override void OnEntry(MethodExecutionEventArgs eventArgs)
        {
            base.OnEntry(eventArgs);
            // Open a new transaction scope with the specified options.
            eventArgs.InstanceTag = new TransactionScope(this._transactionScopeOption);
        }
        /// <summary>
        /// Executed when a method is left.
        /// </summary>
        /// <param name="eventArgs">The event args.</param>
        public override void OnExit(MethodExecutionEventArgs eventArgs)
        {
            base.OnExit(eventArgs);
            // Get the transaction.
            TransactionScope transactionScope = (TransactionScope)eventArgs.InstanceTag;
            // If no exception has been thrown, commit the transaction.
            if(eventArgs.Exception == null)
            {
                transactionScope.Complete();
            }
            // Dispose the transaction scope.
            transactionScope.Dispose();
        }
    }
}

Der entscheidende Punkt innerhalb dieses Attributs ist die Verwendung der Eigenschaft InstanceTag der MethodExecutionEventArgs, die ein beliebiges Objekt aufnehmen und an die aufgerufene Methode anhängen kann – auf diese Art steht der neu erzeugte TransactionScope auch beim Beenden der Methode wieder zur Verfügung.

Review von Painless Project Management with FogBugz

Freitag, 4. September 2009, 21:57 Uhr
Permalink | Kommentare (2) | Kommentare als RSSRSS

Vor einigen Monaten habe ich FogBugz als webbasierte Projektmanagementsoftware vorgestellt, die Peter Bucher und ich seit Ende letzten Jahres für ein gemeinsames Projekt einsetzen.

Mein damaliger erster Eindruck

FogBugz läuft dank intelligenter Nutzung von AJAX extrem schnell, arbeitet bislang fehlerfrei und ist vor allem ausgesprochen intuitiv bedienbar. Man merkt, dass die Software mit viel Liebe zum Detail erstellt wurde, und das Wort hochwertig trifft absolut zu.

hat sich inzwischen mehr als bestätigt: Selten habe ich eine Software erlebt, die derart ausgefeilt und durchdacht ist – und bei der man bereits während der Verwendung das Gefühl bekommt, dass die Anwendung auf sauberem Code im Sinne von Clean Code basiert.

In den vergangenen Tagen habe ich nun das dazugehörige Buch Painless Project Management with FogBugz von Mike Gunderloy gelesen, das sich auf die seit kurzem nicht mehr aktuelle Version 6.0 von FogBugz bezieht – aber dennoch für den Einstieg in FogBugz sehr lesenswert ist.

Nach einem unterhaltsamen Vorwort von Joel Spolsky behandelt das Buch in sechs Kapiteln die folgenden Themen:

  • Managing Projects with FogBugz: Das erste Kapitel beschreibt in einem groben Überblick die Philosophie von FogBugz und demonstriert an Hand eines fiktiven Beispiels, wie der Lebenszyklus eines Falls in FogBugz aussehen könnte.
  • Managing Cases: Das nächste Kapitel beschreibt die verschiedenen Kategorien von Fällen, deren Aufbau sowie die Navigation von FugBugz. Auch auf die verschiedenen Eingabemöglichkeiten für Fälle – vom Webformular über das Einlesen von E-Mails bis hin zur programmatischen Eingabe – wird eingegangen.
  • Making FogBugz Work for You: Das dritte Kapitel beschreibt die Konfiguration von FogBugz, mit einem besonderen Augenmerk auf der Multimandantenfähigkeit der Anwendung: Wie kann eine einzelne Installation von FogBugz so konfiguriert werden, dass sie sämtliche Projekte perfekt abbildet?
  • Getting the Big Picture: Das nächste Kapitel widmet sich ausgesprochen umfangreich dem Thema Projektmanagement und –planung. Dazu wird ausführlich das sogenannte Evidence Based Scheduling vorgestellt, das – zugegeben – die Möglichkeiten von TFS und Project weit in den Schatten stellt.
  • Communicating and Collaborating: Das fünfte Kapitel beschreibt die Möglichkeiten zur internen und externen Zusammenarbeit – insbesondere die Bereiche Wiki, Foren und E-Mail-Integration werden hier abgedeckt.
  • Integrating with FogBugz: Das letzte Kapitel enthält schlussendlich alle übrigen Themen, die sonst nirgendwo Platz gefunden haben. Dies reicht dabei von der Integration einer Versionsverwaltung über die REST-API von FogBugz bis hin zur automatischen Erstellung von Bugreports aus .NET heraus.

Alles in allem lernt man also ausgesprochen viel über FogBugz, zudem liest sich das Buch sehr flüssig. Außerdem ist positiv anzumerken, dass der Autor das Buch sehr kompakt gehalten hat – es umfasst gerade einmal 197 Seiten, enthält aber dennoch alle wissenswerten Details.

Gerade im Vergleich zu der doch sehr teuren und administrativ aufwändigen Alternative TFS in Verbindung mit Project ist FogBugz eine ganz klare Empfehlung wert – und dieses Buch ebenfalls.

Alles var – oder nicht?

Dienstag, 1. September 2009, 09:37 Uhr
Permalink | Kommentare (4) | Kommentare als RSSRSS

Am 13. Oktober 2008 haben Peter Bucher und ich unter dem Titel Noch Fragen, Bucher? Ja, Roden! angekündigt, jeweils zum ersten eines jeden Monats einen Kommentar zu einem vorab gemeinsam gewählten Thema verfassen zu wollen. Bisher sind in dieser Reihe folgende Kommentare erschienen:

Heute, am 1. September 2009, ist es nun wieder so weit, und unser Thema für diesen Monat lautet:

Alles var – oder nicht?

So wohl Peter wie auch ich haben uns unabhängig voneinander im Vorfeld unsere Gedanken gemacht, wie wir diesem Thema gegenüberstehen. Peters Kommentar findet sich zeitgleich in seinem Blog, folgend nun mein Kommentar zu diesem Thema:

Im Grunde lassen sich die Neuerungen in C# 3.0 auf einen einzigen Aspekt reduzieren: LINQ. Alle Änderungen und Erweiterungen, die C# außer LINQ erfahren hat, sind durch LINQ begründet. Anders formuliert: Wäre LINQ nicht eingeführt worden, wäre kein Bedarf für die anderen Features von C# 3.0 gegeben gewesen.

Obwohl dies nicht der ursprünglichen Intention entspricht, lassen sich diese anderen Features jedoch auch ohne LINQ nutzen:

  • Lambdaausdrücke sind eine kompakte und komfortable Möglichkeit, anonyme Methoden und Eventhandler zu implementieren.
  • Erweiterungsmethoden eignen sich wunderbar, um Methoden für generische Zwecke wie beispielsweise Konvertierung auf elegante Weise an bestehenden Datentypen zur Verfügung zu stellen.
  • Automatisch implementierte Eigenschaften und Objekt- wie auch Listeninitialisierer ersparen dem Entwickler einiges an unnötiger Tipparbeit.

Das einzige Feature, das ohne LINQ nur selten genutzt wird, sind anonyme Typen. Allerdings wird das zugehörige Schlüsselwort var umso häufiger auch abseits von LINQ genutzt. Daraus ergibt sich relativ schnell die Frage, wann var eigentlich genutzt werden sollte und wann nicht: Was sind die Best Practices für den Einsatz von var?

Zunächst einmal bleibt festzuhalten, dass die Verwendung von var nichts an der starken Typisierung von C# ändert: Anders als beispielsweise der weit verbreitete untypisierte Datentyp Variant entbindet das Schlüsselwort var nicht von der starken Typisierung – im Gegenteil, die Typisierung findet ebenso stark statt wie zuvor, nur eben implizit statt explizit.

Was var intern nämlich macht, ist, den Typ des Ausdrucks auf der rechten Seite einer Zuweisung auszuwerten, und diesen Typ für die Variablen auf der linken Seite der Zuweisung zu verwenden. Diese Technik wird – da der Typ hergeleitet wird – auch als Type Inferring bezeichnet.

Prinzipiell kann man also nichts grundlegend falsch machen, wenn man alle explizit angegebenen Typen durch das Schlüsselwort var ersetzen würde. Trotzdem empfiehlt es sich nicht immer: Auf var sollte nämlich dann verzichtet werden, wenn die Lesbarkeit leiden würde, und es nicht mehr auf den ersten Blick offensichtlich wäre, um welchen Typ es sich handelt.

Während beispielsweise die Zuweisung eines generischen Datentyps

var dictionary = new Dictionary<string, int>();

auch ohne explizite Angabe des zu verwendenden Typs problemlos lesbar ist, sieht dies bei den eingebauten Datentypen bereits ganz anders aus:

var number = 2147483746;

Es liegt auf der Hand, dass bei einigen Werten nicht mehr auf den ersten Blick eindeutig zugeordnet werden kann,um welchen Datentyp es sich handelt. Anfällig sind dabei vor allem die folgenden Kombinationen:

  • int oder long?
  • float oder double?

Zieht man außerdem auch noch die nicht-vorzeichenbehafteten Datentypen – wie beispielsweise short oder ulong – hinzu, wird das Chaos perfekt.

Für eingebaute Datentypen sollte das Schlüsselwort var also offensichtlich möglichst nicht verwendet werden. Dies ist der eine Extremfall. Der andere Extremfall sind die anonymen Typen, deren Verwendung ohne das Schlüsselwort var gar nicht erst möglich ist.

Doch wie sieht es zwischen diesen beiden Extremen aus?

Ein Beispiel wurde bereits genannt: Die Lesbarkeit von generischen Datentypen kann durch die Verwendung des Schlüsselwortes var durchaus verbessert werden, immerhin wird durch var an dieser Stelle Redundanz vermieden. Diese Feststellung kann man dabei durchaus zur Regel erheben:

Das Schlüsselwort var kann immer dann guten Gewissens angewendet werden, wenn es redundante Typangaben verhindert – sofern mindestens ein Vorkommen des Typs nach wie vor bestehen bleibt.

Mit dieser Regel hat man bereits die meisten Anwendungsfälle abgedeckt, ansonsten sollte man von var Abstand nehmen.

Eine Ausnahme gibt es jedoch noch: Innerhalb von Schleifen – und hierzu zählen insbesondere auch die foreach-Schleifen – kann für die Definition der Schleifenvariable in der Regel das Schlüsselwort var verwendet werden, sofern auch dann noch auf den ersten Blick ersichtlich ist, von welchem Typ die Schleifenvariable ist.

Zusammengefasst lässt sich also sagen, dass man auf den Einsatz von var zu Gunsten einer besseren Lesbarkeit verzichten sollte – es sei denn, redundante Typangaben werden vermieden. Für Schleifenvariablen kann var verwendet werden, sofern der zugehörige Typ nach wie vor auf einen Blick ersichtlich ist.