Juli 2010 - Einträge

Rehl Factory - eine Singleton Instanz
Montag, 26. Juli 2010 20:10
Die Rehl Factory hat eine Singleton Instanz in die Welt gesetzt:

using System;

/// <summary>
/// Die wunderbare und einzigartige Struktur einer atemberaubenden Singleton.
/// Partial deshalb, weil die Klassendefinition immer mehr und mehr erweitert
/// werden wird.
/// </summary>
public partial class Bianca
{
    /// <summary>
    /// Die einzigartige Instanz.
    /// </summary>
    private static Bianca m_EinzigartigeBianca = new Bianca();

    /// <summary>
    /// Bianca gehört zur Rehl Family und es kann nur über die
    /// Singleton Instanz auf sie zugegriffen werden.
    /// </summary>
    private Bianca()
    {
    }

    /// <summary>
    /// Liefert den Zustand, ob Bianca hungrig ist.
    /// </summary>
    public bool IstHungrig
    {
        get { return GetWunderlicheAntwortObHungrig(); }
    }

    /// <summary>
    /// Liefert den Zustand, ob Bianca gerade schläft.
    /// </summary>
    public bool SchlaeftGerade
    {
        get
        {
            return (!IstHungrig && AugenZu && GleichmaessigeAtmung);
        }
    }

    /// <summary>
    /// Die wunderliche Antwort auf die Frage, ob Bianca hungrig ist
    /// liefert nur die Singleton Instanz mit Hilfe von inneren Zuständen,
    /// die on außen nicht einsehbar sind.
    /// (Trotz .Net und Reflection keine Chance ;-)
    /// </summary>
    /// <returns>True, wenn hungrig, andernfalls False.</returns>
    private bool GetWunderlicheAntwortObHungrig()
    {
        // Miracle, obscure and strange code here
    }
}


Mal schauen, was für Extension Methods sie noch bekommt. Unklar ist auch, wie die künstliche Intelligenz die Internen Datenströme wandern lässt. Und par tout hat sich noch nicht aller Code entschlüsseln lassen, trotz Refector (Ultraschall), oder genauerer Analyse. Ein Debuggen war leider nur von außen möglich. Die Factory und auch die Helferinstanzen (Ärzte) sind sich aber einig, sie lebt und sie ist gesund ;-)

Ich habe in den embedded Ressourcen noch ein Bild gefunden:


Die ist ja soo goldig ;-)))
BizTalk2010 - Host Instanz hält einen Eintrag in der MessageBox
Donnerstag, 22. Juli 2010 07:51
Wir haben mit den Tests unter BizTalk2010 festgestellt, dass die MessageBox nicht von Grund auf leer ist. Eine Rückfrage bei der Microsoft Produktgruppe hat ergeben, dass wohl eine Host-Instanz einen internen Eintrag in der MessageBox vornimmt. Der Eintrag ist keiner Service- bzw. Messageinstanz zuzuordnen.

Siehe auch Microsoft Connect.

Das "Schlimme" daran ist, dass selbst eine WMI Abfrage "SELECT * FROM MSBTS_MessageInstance" diesen internen Eintrag zurückliefert, und das glaube ich nicht, dass das "ByDesign" ist. Wir werden da nachhaken.
von Timo Rehl | mit no comments
Abgelegt unter: ,
MSSQL Server alle Tabellen- und Spaltennamen aufisten
Samstag, 10. Juli 2010 14:03
Wer die komplette Struktur einer Datenabank einmal ausgeben lassen möchte, der kann das mit folgenden SQL Zeilen sehr schnell realisieren:
SELECT SysObjects.[Name] as TableName, SysColumns.[Name] as ColumnName, SysTypes.[Name] As DataType, SysColumns.[Length] As Length
FROM SysObjects
INNER JOIN SysColumns ON SysObjects.[Id] = SysColumns.[Id]
INNER JOIN SysTypes ON SysTypes.[xtype] = SysColumns.[xtype]
WHERE SysObjects.[type] = 'U'
ORDER BY SysObjects.[Name]
VisualStudio Debug Visualizer für Dictionary
Freitag, 9. Juli 2010 14:04
Dieser Artikel wurde zum 1. Mal am 09.07.2010 upgedatet

Ich habe nun sehr oft das Problem, dass ich in VisualStudio in einer Debug Session den Inhalt eines Dictionaries mir anzeigen, oder gar verändern möchte. Dictionaries sind bei mir recht häufig als Übergabeparameter definiert.

Was sind "Debug Visualizer"?

Debug Visualizer kennt jeder (aber wahrscheinlich nicht mit dem Begriff ;-). Ein berühmtes Beispiel ist der String-Visualizer:



Ich habe nun für VisualStudio 2005 und 2010 einen eigenen Visualizer für Dictionaries geschrieben.

Dictionary Visualizer Solution Aufbau:


Ein eigner Visualizer ist grundsätzlich vom Aufbau her immer gleich:
- Der Visualizer ist eine Class Library
- Es existiert eine Einstiegsklasse, die vom VS Debugger aufgerufen werden kann
- Es gibt ein Datenobjekt, das der Debugger zum (de-)serialisieren verwendet
- In der AssemblyInfo stehen die Informationen, damit VS weiß, welche Objekte mit dem Visualizer angezeigt werden können

In meinem Beispielprojekt ist das so aufgeteilt:
- DictionaryVisualizer.cs => Einstiegsklasse, die von der abstrakten Klasse DialogDebuggerVisualizer abgeleitet ist
- DictionarySource.cs => Die Datenklasse, von VisualizerObjectSource abgeleitet
- frmDictionaryVisualizer.cs => Das anzuzeigende Dialogfenster (äußerst trivial gehalten ;-)
- DataTableConverter.cs => Hilfsklasse, die Konvertierungen von und zu DataTables realisiert

Beschreibung der einzelnen Bestandteile:

DictionaryVisualizer.cs:

    /// <summary>
    /// Visualisiert ein Dictionary in einer Debug Session.
    /// </summary>
    public class DictionaryVisualizer : DialogDebuggerVisualizer
    {
        /// <summary>
        /// Zeigt einen modalen Dialog, das den Inhalt des Dictionaries visualisiert.
        /// </summary>
        /// <param name="windowService">Der Windows Context, in dem der Debugger läuft.</param>
        /// <param name="objectProvider">Das Dictionary-Objekt, das visualisiert werden soll.</param>
        protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
        {
            IDictionary dictToShow = null;
            
            // Versuchen, das Objekt aus dem Debugger zu extrahieren
            try
            {
                dictToShow = objectProvider.GetObject() as IDictionary;
            }
            catch (Exception ex)
            {
                MessageBox.Show(
                    String.Format("Folgender Fehler ist aufgetreten:\n{0}\nStack:\n{1}", ex.Message, ex.StackTrace),
                    "Fehler",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);

                // Fehler werden ausgegebenund weitere Schritte werden ignoriert
                dictToShow = null;
            }

            // Dictionary anzeigen lassen
            if (dictToShow != null)
            {
                using (frmDictionaryVisualizer dialog = new frmDictionaryVisualizer())
                {
                    dialog.Data = DataTableConverter.ConvertFromDictionary(dictToShow);
                    windowService.ShowDialog(dialog);
                    objectProvider.ReplaceObject(DataTableConverter.ConvertToIDictionary(dialog.Data, dictToShow.GetType()));
                }
            }
        }
    }

Die Methode Show wird vom Debugger ausgeführt, wenn auf die Lupe gedrückt wird (siehe TextVisualizer-Bild oben). Der Ablauf ist Straight-Forward:
- Zunächst wird versucht das eingehende Objekt aus dem objectProvider in ein IDictionary Objekt zu casten
- Sollte das geklappt haben, so wird aus dem Objekt ein DataTable Objekt konvertiert und dem Dialog übergeben
- Ist der Dialog zurückgekehrt, so wird dessen DataTable in ein neues Dictionary des gleichen Typs gewandelt und dem Debugger zurückgegeben

DictionarySource.cs:

    public class DictionarySource : VisualizerObjectSource
    {
        public override void GetData(object target, System.IO.Stream outgoingData)
        {
            IDictionary dictToSerialize = target as IDictionary;
            if (dictToSerialize != null)
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(outgoingData, dictToSerialize);
            }
        }
    }

Ebenfalls sehr einfach gestrickt. Hier wird die Methode GetData überschrieben, damit eine eigene Serialisierung des IDictionary Objektes stattfinden kann. Das ist quasi nur ein BinaryFormatter Wrapper.

AssemblyInfo.cs:

Hier ist es wichtig, dass über Attribute definiert wird, welche Objekte für einen Visualizer überhaupt in Frage kommen. Das definiert sich folgendermaßen:
[assembly: System.Diagnostics.DebuggerVisualizer(typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionaryVisualizer),
           typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionarySource),
           Target = typeof(System.Collections.DictionaryBase),
           Description = "Visualize IDictionary")]
[assembly: System.Diagnostics.DebuggerVisualizer(typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionaryVisualizer),
           typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionarySource),
           Target = typeof(System.Collections.Hashtable),
           Description = "Visualize IDictionary")]
[assembly: System.Diagnostics.DebuggerVisualizer(typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionaryVisualizer),
           typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionarySource),
           Target = typeof(System.Collections.Specialized.ListDictionary),
           Description = "Visualize IDictionary")]
[assembly: System.Diagnostics.DebuggerVisualizer(typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionaryVisualizer),
           typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionarySource),
           Target = typeof(System.Collections.Specialized.HybridDictionary),
           Description = "Visualize IDictionary")]
[assembly: System.Diagnostics.DebuggerVisualizer(typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionaryVisualizer),
           typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionarySource),
           Target = typeof(System.Collections.Specialized.OrderedDictionary),
           Description = "Visualize IDictionary")]
[assembly: 
System.Diagnostics.DebuggerVisualizer(typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionaryVisualizer),
          
 typeof(Rehl.DebuggingTools.DictionaryVisualizer.DictionarySource),
          
 Target = typeof(System.Collections.Generic.Dictionary<,>),
          
 Description = "Visualize IDictionary")]

Der Aufbau ist fast selbsterklärend. Der erste Parameter einer jeden Visualizer Definition ist der entsprechend aufzurufende Visualizer. In meiner ClassLibrary gibt es nur den einen DictionaryVisualizer. Der zweite Parameter bestimmt das Objekt, das zum (de-)serialisieren verwendet wird. Hier also auch immer wieder nur eines, nämlich das DictionarySource. Das Target definiert das Objekt, für welches der Visualizer gelten soll. In meiner Sammlung werden also DictionaryBase, Hashtable, ListDictionary, HybridDictionary und OrderedDictionary unterstützt.

Leider habe ich bis jetzt keine Möglichkeit gefunden generische Objekte hierfür definieren zu können. Wenn hier einer mehr weiß, dann kann er mir die Info gerne zukommen lassen, das wüde ich auch mit einbauen. Als Workaround kann man im Debugger ohne Probleme ein generisches Dictionary zu einem statischen casten und dnn die Visualisierung darauf laufen lassen.
Update: Inzwischen habe ich es herausgefunden, das war zu einfach ;-)

frmDictionaryVisualizer.cs und DataTableConverter.cs:
Auf diese beiden Bestandteile gehe ich jetzt nicht im Detail ein, das kann jeder nach Interesse selbst in der Solution erforschen.

Installation des Visualizers:
1. Die Solution mit VisualStudio öffnen und einmal als Release durchkompilieren lassen.
2. Dann VisualStudio schließen
3. Die Rehl.DebuggingTools.DictionaryVisualizer.dll aus dem bin/release Ordner in das entsprechende VisualStudio Verzeichnis kopieren, bei mir wäre das z.B. D:\Program Files\Microsoft Visual Studio 10.0\Common7\Packages\Debugger\Visualizers
4. VisualStudio neu starten

Anwendung des Visualizers:
Sollte das Kompilieren und Kopieren abgeschlossen sein, so befindet sich in meiner Solution ein Test Konsolenprojekt, das eine eigene HashTable befüllt und an eine Testmethode übergibt.
Es sollte ein Breakpoint an der Stelle
string s = "OnlyToStopDebugger!";
gesetzt werden und dann Debugging des Projektes gestartet werden (wieder auf Debug umstellen nach einer Installation!).
Jetzt kann, wenn das Programm angahalten hat mit der Maus über den Übergabeparameter IDictionary data gefahren werden, und die Lupe erscheint. Sollte keine Lupe zu sehen sein, dann hat etwas mit der Installation nicht geklappt.
Ein Klick auf diese Lupe lässt das Dialogfenster erscheinen:


Jetzt lässt sich der Inhalt sortieren, und auch editieren.

Besonderes zu beachten:
Sollten eigene Dictionary Implementierungen verwendet werden, dann empfiehlt es sich von einem oben genannten Objekt abzuleiten. Weiterhin muss beachtet werden, dass das Serializable Attribut und eine Implentierung des Sonderkonstruktors für ISerializable vorhanden sin. In meiner Testapplikation wird das realisiert:
    [Serializable]
    public class InheritanceTestClass : Hashtable, ISerializable
    {
        public InheritanceTestClass()
            : base()
        {
        }

        public InheritanceTestClass(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }
    }


Downlaod:
VS2005 Solution
VS2010 Solution
HR - Gehaltserhöhung Template
Dienstag, 6. Juli 2010 06:38
Mein Chef hat mir gezeigt, wie leicht es doch ist über die Abteilung HR eine Gehaltserhöhung zu bekommen. Ich fand das so gut, das muss ich nun hier Euch zeigen:
using System;
using MYCOMPANY.HelperFromHell;

namespace MYCOMPANY.Management.HR.HellWeDontWantThis
{
    public class IncreaseSalary
    {
        private string m_id;
        private decimal m_salary;

        public IncreaseSalary(string idNumberOfEmployee, decimal currentSalary)
        {
            m_id = idNumberOfEmployee;
            m_salary = currentSalary;
        }

        /// <summary>
        /// This is the increase of salary done by HR from time to time.
        /// </summary>
        /// <returns>New salary.</returns>
        public decimal IncreaseItsHr()
        {
            return m_salary;
        }

        /// <summary>
        /// Employee request a higher salary.
        /// </summary>
        /// <param name="whatEmployeeWants">Increase that results from the fucking brain of our brain dead employee.</param>
        /// <returns>New increased salary.</returns>
        public decimal OhNoEmployeeWantsMoreMoneyHowCouldThatHappen(decimal whatEmployeeWants)
        {
            if (Math.Sign(whatEmployeeWants) == 1)
            {
                m_salary = HrHelperFromHell.DoSomeSalaryMagic(m_salary);
                throw new ArgumentOutOfRangeException("whatEmployeeWants", whatEmployeeWants, "The increase is to high! HR Manager was brought to hospital.");
            }
            else
            {
                m_salary += whatEmployeeWants;
            }

            return m_salary;
        }
    }
}


Big Smile