CPWENZ - Developer

Code + UML + more ....

Dependency Injection for Windows Universal Apps

Dependency Injection fördert gut strukturierten, lesbaren und testbaren Code.

Doch wie kann man das in einer Windows Universal App machen? Für .NET Core gibt es von Microsoft ein eigenes Dependency Injection Framework.

In den folgenden Abschnitten wird gezeigt, wie man das Framework zum Laufen bekommt.

Hinzufügen vom Framework

NuGet Paketverwaltung öffnen und Microsoft.Extensions.DependencyInjection installieren

 

Interfaces und Implementierungen erstellen

public interface IPersonProvider
{
    ObservableCollection<Person> AvailablePersons { get; }
    void CreatePerson(string firstName, string lastName);
}

public interface ILoggingService
{
    void Log(string message);
}

internal class PersonProvider : IPersonProvider
{
    private readonly ILoggingService _loggingService;

    public PersonProvider(ILoggingService loggingService)
    {
        if(loggingService==null)
        {
            throw new ArgumentNullException(nameof(loggingService));
        }
        _loggingService = loggingService;
    }

    public ObservableCollection<Person> AvailablePersons { get; } = new ObservableCollection<Person>();

    public void CreatePerson(string firstName, string lastName)
    {
        _loggingService.Log($"{nameof(CreatePerson)} is called with: {firstName} {lastName}");
        AvailablePersons.Add(new Person { FirstName = firstName, LastName = lastName });
    }
}
internal class LoggingService : ILoggingService
{
    public void Log(string message)
    {
        Debug.WriteLine("Log: " + message);
    }
}

Zugriff ermöglichen

Im Code sollten nur noch die Interfaces benutzt werden und keine Konstruktoren explizit aufgerufen werden.

Mit folgender singleton Klasse können wir Instanzen anfordern:

public class ResolutionRoot
{
    public static ResolutionRoot Instance { get; } = new ResolutionRoot();
    public IServiceProvider Container { get; }

    private ResolutionRoot()
    {
        ServiceCollection services = new ServiceCollection();
        RegisterServices(services);
        Container = services.BuildServiceProvider();
    }

    private void RegisterServices(ServiceCollection services)
    {
        services.AddTransient<ILoggingService, LoggingService>();
        services.AddTransient<IPersonProvider, PersonProvider>();
    }
}

Um nun einen Person-Provider zu bekommen, reicht folgender Aufruf:

ResolutionRoot.Instance.Container.GetService<IPersonProvider>();

Dabei wird automatisch eine LoggingService-Instanz mit angelegt, da der Konstruktor von PersonProvider diese benötigt.

Wenn in folgender Zeile: services.AddTransient<IPersonProvider, PersonProvider>();

Statt AddTransient die Methode AddSingleton benutzt wird, sorgt das Framework dafür, dass immer die gleiche Instanz genommen wird.

Aspekt orientierte Programmierung ohne ein Framework

Aspekt orientierte Programmierung wird immer beliebter und viele gute Frameworks sind verfügbar, die einem dabei helfen. Jedoch kann man auch ganz ohne ein Framework aspekt orientiert programmieren.

Folgender Code Ausschnitt zeigt eine Methode mit dessen Hilfe ich Methoden Nutzungen loggen kann:

public static T CallWithLogging<T>( Expression<Func<T>> toCall)
{
       Console.WriteLine($"1: Call function {toCall.Body}");
       T result = toCall.Compile()();
       Console.WriteLine( "1: Result of Function call: " + result );
       return result;
}

Expression<Func<T>> stellt ein ExpressionTree dar, der durch toCall.Compile() zur Laufzeit kompiliert wird. Mit toCall.Body kann der übergebene Ausdruck als String ausgegeben werden.

Die CallWithLogging<T> Funktion kann wie folgt benutzt werden:

int max1 = FunctionExtension.CallWithLogging(() => Math.Max(3, 4));
Console.WriteLine($"max1:{max1}");

Die Konsolen Ausgabe wäre dann wie folgt:

1: Call function Max(3, 4)
1: Result of Function call: 4
max1:4

Alternativ zum Expression Tree kann man auch direkt ein Action<...> oder Func<...> reingeben und einfach mal einen Performance Tester implementieren:

public static void PerformanceTest(Action toExecute)
{
      Stopwatch stopWatch = new Stopwatch();
      stopWatch.Start();
            toExecute();
      stopWatch.Stop();
      Console.WriteLine("Execution takes: " + stopWatch.ElapsedMilliseconds + " milliseconds.");
}

Die Benutzung der Funktion kann dann wie folgt aussehen:

FunctionExtension.PerformanceTest(() =>
{
    Thread.Sleep(300);
    Console.WriteLine("Nearly finished!");
    Thread.Sleep(100);
});

 

LINQ - Examples

In diesem Beitrag möchte ich Anregungen geben, wie man effektiv mit LINQ-Queries arbeiten kann.


CSV-Content auslesen und verarbeiten

public static string[] CSV_CONTENT =new string[]
{
    "Datum;Name;Distanz",
    "1.1.2015;Ca;200",
    "2.1.2015;We;300",
    "2.1.2015;We;100",
    "2.1.2015;Ca;150",
    "12.2.2015;Ca;50",
};
static void ParseCSV()
{
    // Skip Header:
    IEnumerable<string> rowsWithContent = CSV_CONTENT.Skip(1);
    // Split rows into columns:
    IEnumerablee<string[]> data = rowsWithContent.Select(x => x.Split(';'));
    // Filter all wrong rows:
    IEnumerablee<string[]> correctData = data.Where(row => row.Length == 3 && row.All(cell=>!string.IsNullOrEmpty(cell)));
    //Generate Datastructure:
    var richData=correctData.Select(row=>
        new {
            DatePoint=DateTime.Parse(row[0]),
            Name=row[1],
            Distance=uint.Parse(row[2])
        });
    // Read out data:
    Console.WriteLine("Total Minimum: {0} | Total Maximum: {1}", richData.Min(x => x.Distance), richData.Max(x => x.Distance));
    var personResults = richData.GroupBy(x =>? x.Name);
    foreach (var item in personResults)
    {
        Console.WriteLine("Result of: " + item.Key);
        Console.WriteLine("   First entry: " + item.Min(x => x.DatePoint));
        Console.WriteLine("   Last entry: " + item.Max(x => x.DatePoint));
        Console.WriteLine("   Total distance: " + item.Sum(x => x.Distance));
    }
}

Reflection in C#

Mit Reflection kann man Klassen, Typen, Methoden, ... von außen betrachten und benutzen. So erlaubt Reflection eine Instanz einer Klasse zu erstellen und darauf Methoden aufzurufen, die zur Compile-Zeit noch nicht bekannt sind. Außerdem ist es so möglich den Inhalt einer DLL (Klassen, Methoden, ...) aufzulisten ohne den Quellcode zu kennen.

Wie komme ich an Informationen eines bekannten Typs? Antwort: typeof(...)

Wie kann ich den Inhalt einer DLL erfassen? Antwort: Assembly.LoadFrom(...)

In den folgenden Teilabschnitten sind Beispiele (Code-Snipsets) zu sehen, die Zeigen, wie mit Reflection gearbeitet werden kann:

Werte kopieren mit Reflection

public static void CopyValues<a,b>(A from, B to)
{
    Type aType = typeof(A);
    Type bType = typeof(B);
    var aProperties = aType.GetProperties().Where(x => x.CanRead);
    var bProperties = bType.GetProperties().Where(x => x.CanWrite);
            
    foreach (var aProperty in aProperties)
    {
        // Search for equivalent b-Property:
        var bProperty = bProperties.FirstOrDefault(x => 
            x.Name == aProperty.Name && 
            x.MemberType == aProperty.MemberType);
        if (bProperty != null)
        {
            bProperty.SetValue(to, aProperty.GetValue(from));
        }
    }
}

Wie hier zu erkennen ist, werden über die beiden generischen Parameter die Typ-Informationen ausgelesen um danach zu ermitteln, welche Properties vorhanden sind. Bei dem From-Objekt brauchen wir nur lesenden Zugriff auf die Properties und beim To-Objekt nur schreibenden.

Methode aufrufen mit Hilfe eines Strings

public static void CallMethod(object source, string method)
{
    if(source!=null)
    {
        Type typeInfo = source.GetType();
        MethodInfo toCall= typeInfo.GetMethod(method);
        toCall.Invoke(source, null);
    }
}

Mit Invoke wird die eigentliche Methode aufgerufen. Der erste Parameter bestimmt das Objekt und der zweite die Werte für die Parameter der Methode.

Objekte erzeugen

Konstruktoren werden genauso wie Methoden aufgerufen.

Type myType = typeof(A);
ConstructorInfo myConstructor=myType.GetConstructor(Type.EmptyTypes);
object myObject=myConstructor.Invoke(null);

String Search für Objekte

public static IEnumerable<object> SearchStringInObjects(this IEnumerable<object> source, string toSearch)
{
    if (source.Any())
    {
        foreach (var item in source)
        {
            Type typeOfItem = item.GetType();
            foreach (var property in typeOfItem.GetProperties().Where(x => x.CanRead))
            {
                var valueOfProperty = property.GetValue(item);
                if (valueOfProperty != null && valueOfProperty.ToString().Contains(toSearch))
                {
                    yield return item;
                }
            }
        }
    }
}

In diesem Beispiel wird eine Erweiterungsmethode geschriebenm die aus einer Aufzählung alle die Objekte rausfiltert, die ein Property besitzen, das den übergebenen String enthält.

Assembly auslesen

static string ReadAssembly(string filename)
{
    StringBuilder toReturn = new StringBuilder();
    Assembly data = Assembly.LoadFile(filename);
    toReturn.AppendLine("Name of Assembly: " + data.FullName);
    toReturn.AppendLine("Included Types: ");
    foreach (var item in data.GetTypes())
    {
        toReturn.AppendLine(" " + item.FullName);

        foreach (MethodInfo method in item.GetMethods())
        {
            toReturn.AppendLine("  Method: " + method.Name);
        }
        foreach (PropertyInfo property in item.GetProperties())
        {
            toReturn.AppendLine("  Property: " + property.Name);
        }
    }
    return toReturn.ToString();
}

Wie hier zu erkennen ist, wird ein Assembly Objekt angelegt. Über dieses Objekt ist der gesamte Inhalt der Assembly abrufbar.

UML-Tools Empfehlungen

Mit UML können auf graphische Weise die Struktur und das Verhalten von Software modelliert werden. Es gibt eine reihe verschiedener UML-Anwendungen (und Plugins) die bei der Erstellung solcher UML-Modelle helfen. Folgende Tabelle zeigt ein paar dieser Tools und zeigt deren Stärken und Schwächen auf.

KDE Umbrello

Betriebssystem: Linux / Windows (KDE Windows Portierung)
Preis: Kostenlos / Open Source
Website: http://umbrello.kde.org/

Lange Zeit mein Lieblings UML-Tool. Es ist einfach zu benutzten. Erstellte Modelle besitzen Meta-Modell, es ist also kein reines Zeichenprogramm. Es enthält eine Vielzahl verschiedenster UML-Diagramme, die auch auf das selbe Meta-Modell zugreifen. Codegenerierung ist für verschiedene Sprachen möglich.

Star UML

Betriebssystem: Windows
Preis: Kostenlos / Open Source
Website: http://staruml.sourceforge.net/en/index.php

Leistungsstärker als Umbrello, jedoch auch ein wenig komplizierter. Es gibt viele verschiedene Module, mit denen Star UML erweitert werden kann.

UMLet

Betriebssystem: Beliebig / Eclipse
Preis: Kostenlos / Open Source
Website: http://www.umlet.com/

Kleines Plugin für Eclipse. UML Diagramme können gezeichnet werden und durch Texteingabe (mit extra Sonderzeichen) wird das Aussehen bzw. der Inhalt der UML-Elemente bestimmt. Ganz besonders deutlich wird das bei Aktivitätsdiagrammen: http://youtu.be/3UHZedDtr28?t=1m42s

Visual Studio 2010 - 2013 Ultimate

Betriebssystem: Windows
Preis: für Studenten kostenlos
Website: http://www.microsoft.com/visualstudio/deu#2013-Downloads

Eigentlich kein UML-Editor, sondern eine IDE. Es können die gängigsten UML Diagramme erstellt werden: Klassen-, Sequenz-, Anwendungsfall-, Aktivitäts- und Komponentendiagramm erstellt werden. Zwar bietet es nicht so viele Funktionen wie Umbrello und Star UML, jedoch hat es folgende Vorteile:

  • Team Foundation Server Integration --> UML-Elemente können mit Tasks verbunden werden.
  • Visual Studio Integration --> In einem Projektmappen-Verzeichnis Code und Modelle verwalten.
  • Einfache Benutzung --> Läuft sehr stabil und einfach in der Anwendung
  • Plugins --> Es können sehr leicht Plugins geschrieben werden, die auf das Meta-Model der Diagramme zugreifen.

Grapholite

Betriebssystem: Windows 8 (RT) [App], Windows [Desktop] und Web
Preis Windows 8 App: 22,49 € / Demo kostenlos
Website: http://grapholite.com/

Beschreibung bezieht sich auf die App-Version:
Eine Art von Visio für Windows 8 als App. Unterstützt eine Vielzahl verschiedenster Diagramme (unter anderem UML-Diagramme). Codegenerierung und ähnliche Funktionen sind nicht enthalten. Jedoch ist die App eine geniale Möglichkeit um auf einem Windows 8 RT Tablet Klassendiagramme erstellen zu können.

Schrittzähler - Erfahrungen

Schrittzähler (auch Pedometer) ermöglichen die Menge körperlicher Tätigkeiten zu erfassen. Dabei gibt es Schrittzähler in den verschiedensten Ausführungen.

Einsteiger-Modelle

Die günstigsten Modelle kosten um die 3 Euro und erfassen (in der Regel) lediglich die Anzahl der Schritte. Die Anzeige ist ein einfaches LCD-Display und gemessen wird mechanisch (beim Laufen hört man "klick/klack").

Einfache Modelle

Im Bereich von 10 bis 20 Euro sind Modelle zu finden, mit denen die gelaufenen Kilometer und verbrannte Kalorien angezeigt werden.

Erweiterte Modelle - mit Speicher

Ab 20 Euro haben die meisten Modelle zusätzlich noch einen 7 Tage Speicher. Ein paar Modelle (über 40 Euro) haben dazu noch die Möglichkeit Daten per USB mit einem Computer zu synchronisieren.

Spitzen Modelle

Darüber hinaus gibt es Schrittzähler, die Strecken über GPS aufzeichnen oder Extras anbieten wie: Synchronisation über Bluetooth und das zählen von Stockwerken.

Der Anbieter FitBit bietet solche Schrittzähler an. Als Beispiel habe ich hier einen Link auf mein Profil: http://www.fitbit.com/user/25V698

Spielekonsolen

Für Nintendo DS gibt es Laufrythmus DS und der Nintendo 3DS hat einen integrierten Schrittzähler. In beiden Fällen wird das tägliche Laufen mit spielerischen Elementen verbunden.

Apps für das Smartphone

Für alle bekannten Smartphones (Windows Phone, Android und iPhone) gibt es Apps, die mit Hilfe von GPS die gelaufenen Strecken aufzeichnen. Der größte Nachteil an diesen Apps ist es, dass GPS ständig laufen muss und dadurch der Akku des Smartphones sich schneller entlädt. 

 

Microsoft Research Formula - Einführung

FORMULA (Formal Modeling Using Logic Programming and Analysis) ist eine formale Spe-zifikationssprache von Microsoft Research, die sich besonders für Model-based development (MBD) und dem Aufstellen von Spezifikationen eignet. Dabei basiert Formula auf algebrai-schen Datentypen (ADTs) und einer streng-typisierten logischen Programmierung (eng: cons-traint logic programming (CLP)). Zusätzlich bietet Formula Unterstützung für Model Transfor-mationen. Die beiden Sprachen Formula und Prolog (mit Constraints) besitzen zwar einige Ge-meinsamkeiten, jedoch sind Syntax und Ausdrucksmöglichkeiten von Formula umfangreicher.

In den ersten fünf Zeilen des folgenden Formula-Codes wird die domain JobAndPerson definiert, die zwei Datentypen enthält (Person, Job). Die beiden models CompleteModel und Inclomple-teModel definieren nun Instanzen der beiden Datentypen aus der domain JobAndPerson.

domain JobAndPerson
{
  primitive Person ::= (name:String).
  primitive Job ::= (position:String,wage:Integer).
}
model CompleteModel of JobAndPerson
{
  Person("Wenz")
  Job("Student",0)
}
partial model IncompleteModel of JobAndPerson
{
  Person(_)
  Job(_,0)
}

Das erste Model kann mit der Formula-Runtime validiert (CHECK) werden. Dadurch wird ge-prüft, ob das Model die Bedingungen der domain erfüllt. Beim zweiten Model kann Formula Modelle vervollständigen (GET MODEL).

Ein komplexes Beispiel, was Formula kann, ist auf VS-Model-Checker zu finden.

Auf folgender Website ist ein weiteres einführendes Beispiel: http://www.riseforfun.com/Formula/js1

Erweiterung vorhandener Typen in F#

Wie auch in C# werden Erweiterungsmethoden in F# 2.0 unterstützt. In diesem Artikel wird gezeigt, wie das grundlegend geht.

Eine Erweiterung schreiben

Erweiterungen sollten in Modulen zusammengefasst werden, daher wird als Erstes ein Modul definiert (OwnExtension). In diesem neuen Modul wird der Datentyp (Int32) "neu definiert" damit neue members hinzugefügt werden können.

module OwnExtension=
  type System.Int32 with
    member x.addiere_mit zahl = x+zahl

Eine Erweiterung benutzen

Da die Typerweiterung ein Teil von einem Modul (OwnExtension) ist, muss das Modul erst eingebunden werden mit dem Schlüsselwort "open".

open OwnExtension
[<EntryPoint>]
let main(args) =
  let test= (4).addiere_mit(5)
  printfn "4+5= %d" test
  0

F# - Type Provider

Mit der Veröffentlichung des neuen Visual Studio 2012 wird auch eine neue Version von F# ausgeliefert. Eine der Neuerungen von F# 3.0 sind Type Provider, die hier anhand kleiner Beispiele genauer angeschaut werden sollen.

Was sind Type Provider?

Wenn bequem auf eine Datenbank oder einen Webservice zugegriffen werden soll, wird in der Regel eine Menge an Klassen, Felder und Methoden geschrieben (bzw. generiert), um den Zugriff auf die Ressourcen zu kapseln. Das ist zum einen ein Mehraufwand und zum anderen problematisch, wenn sich die Struktur der Ressourcen häufig ändert. Gibt es da nicht etwas Besseres? Und genau dort setzen Type Provider an.

Ein Type Provider stellt Datentypen mit Feldern und Methoden für verschiedene Ressourcen bereit. Diese stehen dem Entwickler während der Programmierung zur Verfügung (IntelliSense und co.).

F# bietet folgende fertige Type Provider:

  • SQL-Datenbanken (SqlDataConnection)
  • OData (ODataService)
  • WSDL-Webservice (WsdlService)

Es ist aber durchaus möglich, auch eigene Type Provider zu implementieren.

Wie können Type Provider benutzt werden?

In den folgenden zwei Beispielen wird der OData Type Provider benutzt.

In dem ersten Beispiel sollen aktuelle Angebote von E-Bay angezeigt werden:

type Catalog = ODataService<"http://ebayodata.cloudapp.net/"> 
let ebay = Catalog.GetDataContext()
for item in ebay.Deals do
  printfn "Der Deal: %s" item.Title

Es ist außerdem möglich, die aktuellen Preise zu erfragen und auf Kategorien zuzugreifen. Im zweiten Beispiel wird auf das Forum StackOverflow zugegriffen:

type Catalog = ODataService<"http://data.stackexchange.com/stackoverflow/atom"> 
let forum = Catalog.GetDataContext()
for item in forum.Posts do
  printfn "Titel: %s" item.Title

Auch hier stehen weitere Daten, wie zum Beispiel Autoren und Kommentare zur Verfügung.

Damit auf die Daten sehr effizient zugegriffen werden kann, gibt es in F# 3.0 zusätzlich noch Query Expressions. Weitere Informationen dazu sind auf folgender Webseite zu finden: http://msdn.microsoft.com/en-us/library/hh225374(v=vs.110).aspx

Quelle und weitere Inforamtionen