Schlagwort-Archive: .NET

Verwenden von Feature-Toggle-Patterns, um der Merge-Hölle zu entgehen

Die Merge-Hölle

Bei der professionellen Software-Entwicklung ist eine Versionsverwaltung nicht mehr wegzudenken. Fast alle Versionskontroll-Systeme unterstützen Branches, in denen man beispielsweise die Entwicklung von Features vornimmt, um den Code im Hauptzweig (trunk) nicht zu beeinflussen und unabhängig das Feature entwickeln zu können:

Hier ist ein Beispiel dafür, wie ich bisher die Produkt- / Projektentwicklung kannte: Nachdem eine Produkt-Version released wurde, werden Feature-Branches angelegt, um die Features unabhängig vom Entwicklungs-Branch zu entwickeln. Das hat sehr viele Vorteile: Beispielsweise könnte sich das Produktmanagement entscheiden, ein Feature erst in einer späteren Version zu integrieren, falls sich die Entwicklung verzögern sollte. Zudem kann die Entwicklung eines Features unabhängig von der Entwicklung anderer Features stattfinden.

Wer so arbeitet, kennt auch den Begriff der „Merge-Hölle“. Diese tritt nämlich dann auf, wenn die Entwicklungs-Branches für unterschiedliche Features und der trunk im Code zu weit auseinander laufen oder Code in der gleichen Datei mehrfach umgebaut wurde. Dann nämlich funktioniert der Merge nicht mehr so einfach:

Wenn es sich dabei nur um eine Code-Datei handelt, ist das zwar ärgerlich, aber noch akzeptabel. Die Merge-Hölle ergibt sich, wenn sehr viele Dateien in unterschiedlichen Entwicklungszweigen verändert wurden und vielleicht sogar noch neue Dateien mit gleichem Namen angelegt wurden. Dann funktioniert in der Regel der Merge nicht mehr und man verbringt Stunden und Tage damit, die Konflikte aufzulösen und hofft, dass danach noch alles so funktioniert, wie es man gedacht war.

Weiterhin kann es passieren, dass Probleme, die in einem Branch gefixt wurden, durch den Merge wieder verloren gehen.

Das Feature Toggle Pattern

Hier kann das Feature-Toggle-Pattern Abhilfe schaffen:

Anstelle der Verwendung unterschiedlicher Entwicklungs-Branches findet sie Entwicklung immer auf dem gleichen Branch (trunk) statt. Martin Fowler hat in seinem Artikel „Feature Toggle“ (http://martinfowler.com/bliki/FeatureToggle.html) detailliert beschrieben, wie das Feature-Toggle Pattern funktioniert.

Damit ist es möglich, auch noch „experimentellen“, noch nicht fertigen Code in Produktivsystemen zu releasen. Man muss quasi nur sicherstellen, dass der unfertige Code nie ausgeführt wird. Dadurch arbeitet jeder immer auf dem aktuellen Entwicklungszweig und kann Änderungen an der Codebasis registrieren und darauf reagieren.

Doch wie setzt man das Feature Toggle Pattern in der Praxis um?

Wichtig ist, dass die Stelle, an der das Feature aktiviert bzw. deaktiviert wird, später einfach zu finden und zu entfernen ist, wenn das Feature „produktiv“ geschaltet wird. Wenn ein Schalter nicht entfernt wird, bürdet man sich unnötigerweise „technische Schulden“ auf. Am einfachsten geht das beispielsweise mit einer (abstrakten) Klasse, die eine Property „IsEnabled“ zur Verfügung stellt und von der alle Feature Schalter erben:

internal
abstract
class
FeatureSwitch

{


public
abstract
bool
IsEnabled { get; set; }

}

 

Von dieser Klasse FeatureSwitch leitet man nun einfach einen Schalter für das eigene Feature („MyFeature“) ab:

internal
class
MyFeatureSwitch : FeatureSwitch

{


private
bool
_isEnabled = true;

 


public
override
bool
IsEnabled

{


get { return
_isEnabled; }


set { _isEnabled = value; }

}

}

Hier wird das Feature by-default eingeschaltet (_inEnabled = true). Genauso einfach kann das Feature auch wieder deaktiviert werden.

Im Code verwendet man den Schalter dann so:

MyFeatureSwitch myFeature = new
MyFeatureSwitch();

 

if (myFeature.IsEnabled)

{


// implement feature code here …

}

else

{

 

}

 

Man instanziiert einfach an einer beliebigen Stelle, an der das Feature verwendet wird, den FeatureSwitch. Dort prüft man dann über die Eigenschaft „IsEnabled“, ob das Feature „scharf geschaltet“ ist und implementiert den Code so, als wenn das Feature produktiv verwendet wird.

Alternativ zur abstrakten Basisklasse „FeatureSwitch“ könnte man auch einen ConfigSwitch verwenden wie ich es beispielsweise im Blog von Federik Normen gesehen habe: http://weblogs.asp.net/fredriknormen/archive/2013/09/28/merge-hell-and-feature-toggle.aspx

Vorlesung .NET: Ergebnisse der Umfrage der Themen im nächsten Semester

Am Ende des letzten Semesters habe ich nach der Bekanntgabe der Noten wieder eine Umfrage zu den Themen der Vorlesung im nächsten Semester gemacht. Mir ist es wichtig, dass ich nicht irgendetwas unterrichte, von dem ich meine, es wäre interessant, sondern dass ich die Themen anspreche und vermittle, die wirklich von Interesse sind.

Das Ergebnis der Umfrage sieht so aus:

20120909-213346.jpg

Platz 1 teilen sich sowohl das Testen von .NET Anwendungen als auch die Verteilung von .NET-Anwendungen, sowie Parallele Datenverarbeitung mit der TPL/Multithreading. In der Firma bin ich in einer Taskforce zu dem Thema Parallelisierung unterwegs und kann bestimmt den einen oder anderen Tipp aus der Praxis vermitteln.

Die folgenden Plätze gehen an GUI Programmierung mit WPF. Hier werde ich neben den Grundlagen in Controls, 2D-, 3D-Programmierung und Animation auch auf MVVM (Model-View-ViewModel eingehen).

Leider hat das Semester nur 10 Vorlesungseinheiten á 3×45 Minuten, sodass andere Themen wie ASP.NET MVC leider auf der Strecke bleiben. Ich wäre aufgrund der aktuellen Entwicklungen wie Windows 8 von einem anderen Ergebnis ausgegangen.

Ich freue mich schon auf das neue Semester, das am 1.10.2012 wieder an der Dualen Hochschule Baden-Württemberg beginnt 🙂

System.IO.FileLoadException: Verwenden von .NET 2.0 Assemblies innerhalb eines .NET 4.0 Prozesses

Verwendet eine .NET 4.0 Assembly .NET 2.0 Komponenten, kommt es zu einer System.IO.FileLoadException mit der detaillierten Meldung „Die Assembly im gemischten Modus wurde während Version v2.0.50727 der Laufzeit erstellt und kann nicht während der 4.0-Laufzeit ohne zusätzliche Konfigurationsinformationen geladen werden.“:

Bei mir lag es einfach daran, dass ich eine UI-Bibliothek verwendete, die für die CLR 2.0 entwickelt wurde, während mein Hauptprojekt in .NET 4.0 entwickelt wurde.

Es gibt mehrere Möglichkeiten, das Problem zu lösen:

–          Über eine Konfigurationsdatei

–          Über das Konfigurierung der Aktivierung via Code

Lösungsmöglichkeit 1: via Konfigurationsdatei

<startup useLegacyV2RuntimeActivationPolicy=“true“>
<supportedRuntime version=“v4.0″/>
</startup>

Die app.config muss natürlich neben der ausführbaren Datei stehen.

Beispiel:

Ausführbare Datei: example.exe
Konfigurationsdatei: example.exe.config

Mark Miller hat in einem Blog-Beitrag (als PDF: marklio – What is useLegacyV2RuntimeActivationPolicy for_) beschrieben, wozu die useLegacyV2RuntimeActivationPolicy nun wirklich gut ist und was sie tut.

Es gibt jedoch Anwendungsfälle, für die man nicht einfach eine Konfigurationsdatei neben die ausführbare Datei legen kann. Ein Beispiel dafür könnte sein, dass eine C-API oder eine COM-API zur Verfügung gestellt wird. Dann kann nicht einfach der ausführbaren Datei, die die C-API verwendet, eine Konfigurationsdatei beigelegt werden.

Lösungsmöglichkeit 2: via Code

Im Blog von Reed Copsey bin ich auf einen interessanten Artikel gestoßen, der genau mein Problem löst: http://reedcopsey.com/2011/09/15/setting-uselegacyv2runtimeactivationpolicy-at-runtime/

Nachfolgend der Code, der für meine Belange (C-API) funktionierte. Jedoch ist die Lösung in Reed Copseys Blog explizit als inoffiziell gekennzeichnet.

public static bool LegacyV2RuntimeEnabledSuccessfully { get; private set; }

staticRuntimePolicyHelper()

{

ICLRRuntimeInfoclrRuntimeInfo =   (ICLRRuntimeInfo)RuntimeEnvironment.GetRuntimeInterfaceAsObject(Guid.Empty,  typeof(ICLRRuntimeInfo).GUID);

try

{

clrRuntimeInfo.BindAsLegacyV2Runtime();

LegacyV2RuntimeEnabledSuccessfully = true;

}

catch (COMException)

{

// This occurs with an HRESULT meaning

// „A different runtime was already bound to the legacy CLR version 2 activation policy.“

LegacyV2RuntimeEnabledSuccessfully = false;

}

}

[ComImport]

[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

[Guid(„BD39D1D2-BA2F-486A-89B0-B4B0CB466891“)]

private interface ICLRRuntimeInfo

{

void xGetVersionString();

void xGetRuntimeDirectory();

void xIsLoaded();

void xIsLoadable();

void xLoadErrorString();

void xLoadLibrary();

void xGetProcAddress();

void xGetInterface();

void xSetDefaultStartupFlags();

void xGetDefaultStartupFlags();

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]

void BindAsLegacyV2Runtime();

}

Interessanterweise wird ein statischer Konstruktor verwendet, der unmittelbar nach dem Laden der assembly ausgeführt wird. Dadurch wird der Code implizit von der Runtime ausgeführt und nicht explizit vom Programm selbst. Das sollte ausreichend gut dokumentiert werden, da potentiell nicht jeder im Team den Code sofort versteht und potentiell den Code als „unnütz“ löschen könnte 😉

Die Eigenschaft „LegacyV2RuntimeEnabledSuccessfully“ gibt an, ob das Umschalten der Runtime-Aktivierung funktioniert hatte. In meinem Fall habe ich eine Ausgabe für die API erstellt, die dem Benutzer angibt, wie er das Problem mithilfe der Konfigurationsdatei lösen kann.

Tutorial iTextSharp: Erstellen von PDF-Objekten

Texte

In iTextSharp werden Texte mithilfe von drei Klassen zusammengesetzt: Chunk, Phrase und Paragraph. Diese sollen in den nächsten Zeilen etwas näher beschrieben werden.

Chunk

Die Klasse Chunk befindet sich im Namespace iTextSharp.text. Chunk stellt die „kleinste“ Einheit in iTextSharp dar. Es besteht aus einem String, bei dem alle Zeichen die gleiche Formatierung (also Schriftart, -größe, -stil und -farbe) besitzen.

Chunk-Objekte besitzen keinerlei Informationen über Zeilenabstände. Das heißt, dass wenn der enthaltene String zu lang ist, wird ein Wagenrücklauf (Carriage return) ohne Zeilenvorschub ausgelöst. Das Resultat ist das, dass die gerade geschriebene Zeile überschrieben wird (ohne gelöscht zu werden). Deshalb sollten Chunk-Objekte in der Regel nicht dazu verwendet werden, direkt einem Dokument hinzugefügt zu werden. Stattdessen sollten sie in Kombination mit anderen Objekten verwendet werden.

Code-Beispiel

Document doc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„Zitate.pdf“));
doc.Open();
Chunk zitatEinstein = new Chunk(„Phantasie ist wichtiger als Wissen, denn Wissen ist begrenzt.“);
Chunk zitatTwain = new Chunk(„Gib jedem Tag die Chance, der schönste deines Lebens zu werden.“);
doc.Add(zitatEinstein);
doc.Add(zitatTwain);
doc.Close();

Ausgabe im Adobe Reader

image

Phrase

Ein Phrase-Objekt (engl. Satz) besteht aus einer Aneinanderreihung von Chunk-Objekten mit einem wichtigen Extra: Wenn ein Zeilenende erkannt wird, dann wird neben den Wagenrücklauf (Carriage Return) auch ein Zeilenvorschub (New Line / Line Feed) ausgelöst, sodass sich die Chunks nicht mehr überschreiben. Der Zeilenabstand wird auch als Leading bezeichnet und kann im Konstruktor als auch in der Leading-Eigenschaft der Phrase-Klasse als float-Wert angegeben werden.

Zusätzlich ist es möglich, eine Hauptschriftart anzugeben, mit der das Phrase-Objekt formatiert wird. Somit erhalten alle enthaltenen Chunk-Objekte die gleiche Formatierung und ein einheitliches Aussehen. Aber ebenso kann man auch jedes Chunk-Objekt einzeln formatieren.

Code-Beispiel

Document doc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„Zitate.pdf“));
doc.Open();
Chunk zitatEinstein = new Chunk(„Phantasie ist wichtiger als Wissen, denn Wissen ist begrenzt.“);
Chunk zitatTwain = new Chunk(„Gib jedem Tag die Chance, der schönste deines Lebens zu werden.“);
Phrase zitate = new Phrase(25);
zitate.Add(zitatEinstein);
zitate.Add(zitatTwain);
doc.Add(zitate);
doc.Close();

Ausgabe im Adobe Reader

image

Paragraph

Das Paragraph-Objekt verbindet mehrere Chunk- und Phrase-Objekte zu einem Absatz (Paragraph, engl. Absatz). Nach jedem Absatz wird automatisch ein Zeilenumbruch erstellt. Das entspricht etwa dem, dass man einem Phrase-Objekt ein Chunk.NEWLINE oder new Chunk(„n“) anhängt.

Die Paragraph-Klasse leitet von der Phrase-Klasse ab und ergänzt diese um einige Funktionen:

image

Abbildung 3: Klassenhierarchie bei Phrase und Paragraph

Der Zusammenhang zwischen Chunk, Phrase und Paragraph soll in folgender Abbildung verdeutlicht werden:

Bild1

Abbildung 4: Zusammenhang zwischen Paragraph, Phrase und Chunk

Initialisierung

Die Paragraph-Klasse besitzt mehrere Konstruktoren:

public Paragraph()
public Paragraph(float leading)
public Paragraph(Chunk chunk)
public Paragraph(float leading, Chunk chunk)
public Paragraph(string str)
public Paragraph(string str, Font font)
public Paragraph(float leading, string str)
public Paragraph(float leading, string str, Font font)
public Paragraph(Phrase phrase)

Ein Absatz kann also aus Chunks, Phrases oder String-Objekten erstellt werden. Über das Font-Objekt kann eine beliebige Schriftart für den Absatz festgelegt werden.

Abstand zwischen den Zeilen festlegen

Zusätzlich unterstützen einige Konstruktoren die Definition von Zeilenabständen (hier leading genannt). Alternativ kann über die Leading-Eigenschaft der Zeilenabstand festgelegt werden.

Abstand zwischen Absätzen festlegen

Den Abstand zwischen einzelnen Absätzen kann über die Eigenschaften SpacingBefore und SpacingAfter gesteuert werden. Dabei wird der angegebene Wert zu dem Wert addiert, der als leading definiert wurde.

Ausrichtung

Als „Besonderheit“ beim Paragraph-Objekt ist die Möglichkeit, Textausrichtungen vorzunehmen. Dazu wird die Methode SetAlignment verwendet. Als Parameter wird ein String erwartet, der als Konstante in ElementTag-Klasse festgelegt ist. Mögliche Werte sind: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFIED, ALIGN_JUSTIFIED_ALL, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM und ALIGN_BASELINE.

Ebenso wäre es möglich, anstatt die SetAlignment-Methode zu verwenden, der Alignment-Eigenschaft einen Wert zuzuweisen. Dieser Wert muss dabei vom Typ integer sein. Auch hier gibt es wieder Konstanten, die zum Setzen der richtigen Ausrichtung verwendet werden – allerdings sind sie in der Element-Klasse definiert: ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, ALIGN_JUSTIFIED, ALIGN_JUSTIFIED_ALL, ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM und ALIGN_BASELINE.

Wann man welche Methode verwendet, ist reine Geschmackssache. Intern wird SetAlignment auf Alignment gemappt.

Nachfolgend ein paar Code-Beispiele für die Textausrichtung im Absatz:

Document doc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„Zitate.pdf“));
doc.Open();
Chunk zitatTwain = new Chunk(„Gib jedem Tag die Chance, der schönste deines Lebens zu werden.“);
zitatTwain.Font = FontFactory.GetFont(„Tahoma“, 24);
Paragraph paragraphTwain = new Paragraph(zitatTwain);

Setzen der Ausrichtung über SetAlignment-Methode

paragraphTwain.SetAlignment(ElementTags.ALIGN_CENTER);
doc.Add(paragraphTwain);
paragraphTwain.SetAlignment(ElementTags.ALIGN_LEFT);

Setzen der Ausrichtung über Alignment-Eigenschaft

doc.Add(paragraphTwain);
paragraphTwain.Alignment = Element.ALIGN_RIGHT;
doc.Add(paragraphTwain);
doc.Close();

Ausgabe im PDF

image

Einrückungen am Absatzanfang

Weiterhin besitzt das Paragraph-Objekt noch die Möglichkeit, Einrückungen am Anfang eines Absatzes einzufügen. Die wird mithilfe der IdentationLeft- und IdentationRight-Eigenschaft.

Tutorial iTextSharp: Writer & Meta-Daten

Das Writer-Objekt

Nachdem nun das Document-Objekt definiert wurde, wird zum Schreiben ein Writer-Objekt benötigt. Dieses entscheidet, wie das Dokument später geschrieben wird. Für jeden „Dokumenttyp“ gibt es ein Writer-Objekt: Beispielsweise wird für PDF-Dokumente ein PdfWriter benötigt, während für TeX-Dokumente ein TeXWriter instanziiert werden muss usw. Das Konzept von iTextSharp ermöglicht auch eine Dokumenttypen und –writer zu erstellen. Diese müssen nur von der abstrakten Klasse DocWriter aus dem iTextSharp.text-Namespace abgeleitet sein.

image

Abbildung 1: Klassenhierarchie DocWriter

Der Konstruktor der Writer-Klassen ist nicht öffentlich (private), sodass mittels GetInstance-Methode ein neues Objekt erzeugt werden muss. GetInstance erwartet zwei Parameter: das Document-Objekt (Das Document-Objekt) und einen Stream, in den die Ausgabe geschrieben wird.

Beispiel für das Erstellen eines neuen PDF-Writers:

Document doc = new Document(PageSize.A4.Rotate());

PdfWriter writer = PdfWriter.GetInstance(doc, File.Create(„test.pdf“));

Zum Schreiben einer PDF-Datei wird das writer-Objekt nicht mehr direkt verwendet (natürlich hält jedes Writer-Objekt einen IDocListener auf das Document-Objekt und wird somit über Änderungen im Document informiert). Stattdessen ermöglicht es weitere Features, auf die in den entsprechenden Kapiteln eingegangen wird:

  • Bearbeiten vorhandener PDF-Dokumente
  • Direktes Zeichnen von Grafiken
  • Verschlüsseln von PDF-Dokumenten
  • Viewer-Einstellungen vornehmen (Anzeige mit/ohne Menüleiste, Vollbild-Modus, Vorschaubilder anzeigen, Seiten-Skalierung etc.)
  • Dateien anhängen

PDF Meta-Daten bearbeiten

Die Meta-Daten im PDF-Dokument beinhalten allgemeine Informationen über das Dokument. Im Adobe Acrobat Reader können die Meta-Daten in den Dokumenteigenschaften (Datei à Dokumenteigenschaften / Strg + D) angesehen werden:

image

Abbildung 2: PDF-Metadaten

Rot hervorgehoben sind die jeweiligen Metadaten, die programmatisch auf dem Document-Objekt gesetzt werden können:

Eigenschaft in den Metadaten

image

Beispiel für das Setzen der Meta-Daten:

doc.AddAuthor(„Ralf Abramowitsch“);
doc.AddCreationDate();
doc.AddCreator(„Mein Tool“);
doc.AddKeywords(„iTextSharp“);
doc.AddKeywords(„Tutorial“);
doc.AddKeywords(„.NET“);
doc.AddSubject(„Thema“);
doc.AddTitle(„Titel“);
doc.AddProducer();

Visual Studio 2008 Express Edition in deutscher Sprache

Seit kurzem stehen die Express Editions von Visual Studio 2008 auch in deutscher Sprache zur Verfügung. Wie auch schon die Express Editions von Visual Studio 2005, sind diese Versionen ebenfalls kostenlos. Der Einsatz für in kommerziellen Projekten ist natürlich auch erlaubt.

Visual Studio 2008 Express

Info: http://www.microsoft.com/germany/express/
Download: http://www.microsoft.com/germany/express/download/default.aspx

Passend dazu gibts natürlich auch die MSDN-Versionen als Hilfedateien zum Download, um nicht bei jeder Anfrage auf die Antwort vom Browser warten zu müssen. (Auch ganz praktisch, wenn man mal mit der Bahn unterwegs ist 😉 )

MSDN Download: http://www.microsoft.com/germany/express/download/msdn.aspx

Wer gern wissen möchte, was ihm zur „Vollversion“ – also Standard oder Professional Edition fehlt – der kann sich unter folgender Seite informieren:

2008er Versionen im Vergleich: http://msdn2.microsoft.com/en-us/vstudio/products/cc149003.aspx

Nützliches Tool für die WinDbg Erweiterung SOS: SOS Assist

Kürzlich bin ich auf das Tool SOS Assist aufmerksam geworden, die eine grafische Oberfläche zu WinDbg SOS anbietet:

SOS Assist

Leider wird das Tool (laut ChangeLog) seit 2006 nicht mehr gepflegt. Im praktischen Einsatz konnte es zwar durch die zahlreichen Infofenster punkten, doch in Punkto Stabilität sind noch einige Defizite zu spüren.

Bisher hatte ich mir immer mit ClrDump (http://www.debuginfo.com/tools/clrdump.html) beholfen, welches mir CrashDumps zur Analyse erstellte. Diese konnte ich dann im WinDbg laden und mittels SOS-Erweiterung analysieren.

Screenshots: http://old.thinktecture.com/SOSAssist/Screenshots.htm

Download: http://old.thinktecture.com/SOSAssist/default.html

Übrigens: Zum Thema CrashDump-Analyse zum Aufspüren von Sicherheitslücken hat auch das MSDN-Magazin einen Artikel veröffentlicht: http://msdn.microsoft.com/msdnmag/issues/07/11/ExploitingCrashes/default.aspx?loc=de

Sehr lesenswert!

Microsoft gibt mit VS2008 den Quellcode für .NET-Klassenbibliotheken frei

Wie ich heute erfahren habe, gibt Microsoft den Quellcode für verschiedene Klassenbibliotheken frei. Bisher war es ja nicht möglich, in die Klassenbibliotheken rein zu debuggen. Das habe ich im Gegensatz zu Java schon sehr vermisst.

Welche Bibliotheken werden dabei sein?

  • Base Class Libraries (mscorlib.dll)
  • ASP.NET (System.Web.dll)
  • Windows Forms (System.Drawing.DLL & System. Windows.Forms.dll)
  • ADO.NET (System.Data.DLL)
  • XML (System.Xml.DLL)
  • WPF (System.Windows.DLL)

Leider wird der Code unter der Microsoft Reference License veröffentlicht. Heißt im Klartext: Gucken, aber nicht anfassen.

Wenn man einen Fehler im .NET Framework entdeckt, dann darf man sich freuen ihn gefunden zu haben – und wenn man ihn meldet, dann wird er  (vielleicht) bald gefixt. (frei nach dem Motto: Wer einen Fehler findet, darf ihn behalten).

WinDbg-Erweiterung für verwalteten Code: SOSEX

Neue Debugger-Befehle in dieser Erweiterung sind:
!dumpgen and !gcgen
Herausfinden, welche Objekte sich in welcher Generation der GarbageCollection befinden (z.B. !dumpgen 2 zeigt eine Liste der Objekte an, die sich in GC-Generation 2 befinden)

!refs
Zeigt alle Referenzen auf ein bestimmtes Objekt

!dlk
DeadLock detection – zur Erkennung von DeadLocks (sich behindernde Threads)

!bpsc and !bpmo
bpsc (BreakPoint Source) erlaubt das nachträgliche Setzen von Source-Breakpoints im Code an einer bestimmten Code-Zeile

!vars and !isf
Wenn an einem Breakpoint angehalten wurde, so kann mithilfe von !vars die lokalen Variablen angeschaut werden.

Mehr Infos zu den Erweiterungen gibts im Blog von Steve Johnson:
http://www.stevestechspot.com/SOSEXANewDebuggingExtensionForManagedCode.aspx

und im Blog von John Robbins:
http://www.wintellect.com/cs/blogs/jrobbins/archive/2007/06/19/great-sosex-a-phenomenal-net-debugging-extension-to-see-the-hard-stuff-steve-johnson-is-my-hero.aspx

Download x86-Edition: http://www.stevestechspot.com/downloads/sosex_32.zip
Download x64-Edition: http://www.stevestechspot.com/downloads/sosex_64.zip

Download-Tipp: Windows Server 2008 Developer Training Kit (Beta 3)

Für Software-Entwickler für Windows Server 2008 gibt es das Developer Training Kit als kostenlosen Download.

Darin enthalten sind Hands-On-Labs und Präsentationen für den IIS7, Management, Windows Communication Foundation, Windows Workflow Foundation, Windows CardSpace, Windows PowerShell, Virtualisierung und das Transactional File System (TxF).

Auch enthalten ist die Technologie-Demo-Applikation „DinnerNow„. 

Windows Server 2008 Developer Training Kit

Hier ein kleiner Vorgeschmack anhand einiger Screenshots:

Windows Server 2008 Developer Training Kit Windows Server 2008 Developer Training Kit Windows Server 2008 Developer Training Kit

Ist alles echt nett gemacht! Sollte man sich als Entwickler unbedingt mal ansehen.

Download (57.1 MB):
http://www.microsoft.com/downloads/details.aspx?FamilyId=B36EE81A-AFF5-4314-95D7-DAD3ACFA8094&displaylang=en

[Update 05.02.2008]
Die Release-Version des Trainingskits ist zum Download (125,9MB) verfügbar:
http://www.microsoft.com/downloads/details.aspx?familyid=8BDAA836-0BBA-4393-94DB-6C3C4A0C98A1&displaylang=en