Audit Logs/Trails

Was sind Audit Logs?

Ein Audit Log ist eine Art Informationen über Änderungen zu persistieren und organisieren. Einen Audit Log soll die Änderungen und Zeit einer Änderung zu spezifischen Daten rapportieren und es in einem File oder Datenbank persistieren. Jeder Eintrag eines Audit Logging System heiss Audit Trail und durch die Zusammenfassung allen Trails, kann den Verlauf der Daten eines Systems erstellt werden und, wenn nötig, den originalen Zustand der Daten wiederherstellen zu können.

Der Hauptzweck des Audit Logs ist die Sicherheit der Daten zu halten. Mit der Einsetzung von Audit Logs können Entwickler wissen, was und wann etwas geändert worden ist und das wichtigste, von wem sind die Änderungen gekommen. Bei Einbrechen im System, können die Audit Logs zeigen, wo und wie Schaden gemacht worden sind.

Sehr oft werden Audit Logs in Files gespeichert und das einfachste Format diese Logs zu speichern ist ASCII. ASCII hilft bei der Lesbarkeit den Logs und benötigt keine spezielle Software, um diese zu lesen oder schreiben. Es gibt anderen Formaten, die alles besser organisieren aber können nur durch Speziellen Softwaren, wie Frameworks erfasst werden. Ein von diesen Formaten ist XML.

Eine andere Art Augit Trails zu persistieren, ist in einer Datenbank Tabelle. Mit der Hilfe von SQL Skripts können die Trails mit wenig Aufwand angezeigt und filtriert werden.

Beim Eintragen von Audit Trails ist es sehr wichtig, dass den vorherigen und neuen Wert der Daten in jedem Eintrag gespeichert wird. Meisten Einträge werden sehr ähnlich sein aber bei kleinen Fällen kann man grosse Unterschiede merken und die Integrität der Daten halten.

Wenn soll es benutzt werden?

Audit Logs sind sehr simple und im Vergleich zu anderen Patterns merkt man, dass es die Audit Logs einigen Einschränkungen haben. Anderen Patterns wie Temporal Property und Temporal Object können Objekte sehr komplex machen und fokussieren sich mehr an dieser Komplexität zu verstecken als effizient zu sein.

Das prozessieren von Audit Logs kann bei grossen Mengen sehr ineffizient sein. Wenn man viele Trails erstellt und sie braucht, um der Verlauf der Daten zu produzieren, wird den Code dafür sehr langsam sein. Die Spezifizierung den Trails bei den Audit Logs kann den Prozess der Erstellung eines Verlaufs sehr komplex machen und es ist empfohlen verschiedene Patterns dafür zu brauchen. Man kann einerseits Audit Logs brauchen, um die Änderungen für spezifischen Momenten zu speichern, wie grosse Updates zu speichern und andere Patterns für die Erstellung und Löschung von neuen Einträgen.

Das Persistieren den Audit Logs in einer Datenbank kann sehr hilfreich sein, da SQL bei grossen Datenmengen sehr effizient ist. Die Nutzung von mehreren Tabellen oder sogar eine eigene Datenbank dafür kann den Prozess ein Bisschen komplexer aber organisierter machen.

Referenzquellen:

https://de.wikipedia.org/wiki/Audit_Trail

https://martinfowler.com/eaaDev/AuditLog.html

Tutorials:

.NET MVC:
https://www.c-sharpcorner.com/article/audit-trail-and-data-versioning-with-c-sharp-and-mvc/

Advertisements

Office Open XML

Abgekürzt OOXML ist eine, von Microsoft entwickelte, Dateiformate zur Speicherung von Bürodokumente (Word-Dateien) auf XML-Basis.

OOXML besteht aus einer Spezifikation für ein Conainerformat, den Open Packaging Convetions und einer Reihe von XML-basierten Auszeichungssprachen für die einzelnen Komponenten eines Büroanwendungspaketes. Ein Package ist eine ZIP-Datei, die alle Bestandteile eines Dokuments enthält. Also ein Word Dokument ist schlussendlich eine ZIP-Datei, die eine solches Package entspricht.

Ein Package besteht aus mehreren Parts und Items. Die Parts und Items lassen sich in der XML Code erkennt werden. Parts sind die einzelnen Bestandteile des Inhalts des Dokuments (Text, Grafiken, Bilder, Tabellen, usw.), während Items beschreibende Metadaten sind, die beschreiben, wie die Parts des Dokuments dargestellt werden sollen. Items können Relationship Items oder Content-Type Items sein. Relationship Items beschreiben, wie zwei Parts zusammenhängen und zusammengefügt werden müssen. Content-Type Items zeigen, wie die einzelnen Parts dargestellt werden müssen. Jedes Dokument hat eine Main Part.

Es gibt fünf Auszeichungssprachen für OOXML:

  • WordprocessingML für Textverarbeitungsdokumente
  • SpreadsheetML für Tabellenkalkulationsdokumente
  • PresentationML für Präsentationsdokumente
  • DrawingML für Zeichnungsdokumente
  • VML für Zeichnungsobjekte innerhalb anderer Dokumente

In diesem Blogpost werde ich mich auf der WordprocessingML fokussieren und die entsprechende Entwicklungsframework für C#.

Ei Word Dokument enthält im root Ordner der ZIP-Datei eine XML-Datei mit dem Namen /[Content_Types].xml und drei Verzeichnisse /_rels, /docProps und ein Verzeichnis mit den Dokumentdaten.

Die [Content_Types].xml-Datei enthält eine Beschreibung des Inhaltes der ZIP-Datei. Die _rel-Verzeichnis hat alle Abhängigkeiten zwischen den einzelnen Parts. Pro Part gibt es eine Datei. In der docProps-Verzeichnis befinden sich verschiedene Dokumenteigenschaften (Metadaten) wie Autor, Speicherdatum usw. Die Dokumentdatenverzeichnis hat den Text des Word Dokuments in der entsprechenden document.xml Datei.

Einen einfachen Word Dokument sieht so aus:

xmlWord

Einen Word Dokument habt immer die <w:wordDocument> und <w:body> Tags. Alle Tags in einer Word Datei haben das Präfix «w». In der <wordDocument> Tag kann man spezifische Eigenschaften des Dokuments definieren. In der <body> Tag kommen alle visuellen Elemente. Einen normalen Text ist ein Paragraf und hat den Tag <p>. Den Text kommt in einem speziellen Tag, die sogenannte Run Tag <r>. Im <r> Tag kann man Text in einen <t> Tag schreiben. Den XML Code sieht sehr chaotisch aus, da alle Tags den abgekürzten Namen eines Elements haben. Es kann sehr mühsam sein, eine WordXML Datei zu editieren, dafür kann man es mit der Hilfe von Programmiersprachen ein Skript schreiben, den die Generierung des XMLs Codes übernimmt.

Ich werde jetzt die Grundlage für die Generierung von Word Dateien mit C# erklären.

Damit wir programmieren können, brauchen wir das DocumentFormat.OpenXML Nuget Package.

csWordcode

Die WordProcessingDocument Klasse wird gebraucht, um einen Word Dokument zu erstellen. Danach muss unser Dokument eine Main Part haben, dafür addieren wir die MainDocumentBodyPart in dem Dokument. Die Main Part enthält den Body des Dokumentes und im Body, können wir ein Paragraf mit Text einfügen. Es ist sehr wichtig, dass den Text Element in einem Run Element ist!

Den XML Code sieht nachher so aus:

helloWordXml

Mobile Entwicklung

Bei der Entwicklung von Mobile Apps muss man wissen, dass es drei verschiedene Typen von Apps gibt. Jeden Typ hat seiner Vorteile und Nachteile gegenüber den anderen Zwei. Die drei Typen sind die Folgende:

Native App

Eine Native App ist eine Applikation, die «native» (einheimisch) für einen Betriebssystem ist. Das heisst, dass die App für einen spezifisch Betriebssystem (z.B. Android) entwickelt wird und dieselbe App läuft den nur auf diesem Betriebssystem und muss auf dem Gerät installiert werden. Wenn man die App für einen anderen Betriebssystem verfügbar machen will, muss eine zusätzliche App für den Betriebssystem entwickelt werden.

Mit den folgenden Programmiersprachen können Native Apps programmiert werden:

  • Java, Kotlin, C++ für Android
  • Swift und Objective-C für Apple iOS
  • C#, C, C++ und JavaScript für Windows Phone

Die Vorteile von Native Apps sind:

  • Die Apps sind für einen Plattform spezifisch eingerichtet. Die Guidelines für die Plattform werden eingehalten und es gibt einen einheitlichen Look & Feel mit dem System.
  • Alle Libraries aus dem Development Kit für den System können verwendet werden. Zum Beispiel können Java-Libraries für Android verwendet werden.
  • Können performant auf Hardwarefunktionen und Sensoren zugreifen und Daten auf dem Gerät speichern.

Die wenige Nachteile sind:

  • Hoher Entwicklungs- und Wartungsaufwand. Für jedes Betriebssystem muss eine neue App entwickelt werden.
  • Verfügbarkeit auf anderen App Stores.

Hybride App

Eine Hybride App ist eine Mischung aus einer Native App und einer Web App. Damit können die Vorteile beider Architekturen erhalten werden.

Eine Hybride App ist nicht mehr als eine Native App die einer Web App, durch eine Web View, anzeigt. Alle Funktionalitäten der App werden als eine Web App entwickelt und die Web App wird danach von der Native App in der Web View angezeigt. Damit muss den Benutzer nur die Native App in der App Store herunterladen. Alle Funktionen, wie Zugriff auf Sensoren oder Systeminteraktionen werden dann vom nativen Teil der App gemacht.

Für die Entwicklung von Hybriden Apps gibt es mehreren Entwicklungswerkzeuge, die erlauben, den Code der hybriden App einmal zu schreiben und dann für mehrere Plattformen kompiliert werden.

Der Vorteil von Hybriden Apps ist, das Verknüpfen von mehreren Vorteilen von Native und Web Apps wie den Zugriff auf die Systemfunktionalitäten einer Native App und die Plattformunabhängigkeit einer Web App.

Die Nachteile sind:

  • Das GUI sieht aus wie eine normale Web App und kann nur mit UI-Frameworks nah an das Look & Feel einer Native App kommen.
  • Performance ist schlechter als bei einer Native App

Progressive Web App (PWA)

Progressive Web Apps sind Web Applikationen eine spezielle Art von Mischung aus Native und Web Apps, ähnlich wie einer Hybride App. Eine Web App sieht aus wie einer installierte (native) App aber verhaltet sich wie eine Webseite.

Die Merkmale eine PWA sind:

  • Läuft im Browser wie einer Web App aber das Icon kann auf dem Startbildschirm abgelegt werden
  • Die App ist anpassungsfähig und Plattformunabhängig
  • Obwohl sie eine Web App ist, kann sie trotzdem ohne einer Online-Verbindung laufen
  • Den Benutzer hat immer die aktuellste Version
  • Die App ist über eine HTTPS-Verbindung gesichert
  • Die App kann als Link geteilt werden

 

Version Control

Centralised vs Distributed Version Contol Systems

Ein zentralisiertes Versionierung Control System funktioniert mit einem Client-Server Modell. Es gibt eine einzige Hauptkopie des Codes. Code Schnipseln, die geändert werden, sind normalerwiese gesperrt oder «checked out» damit nur eine einzige Person erlaubt ist, diese Änderungen zu machen. Wenn die Änderungen gesichert werden, wird die Datei wieder entsperrt und den anderen Entwicklern können nun den File bearbeiten. Sobald jeder Teammitglied seine Änderungen gesichert hat und es Zeit wird, eine Release zu erstellen, werden allen Modulen gesammelt und zusammen kombiniert.

Ein dezentralisiertes Versionierung Control System arbeitet mit einem Peer-to-Peer Modell. Den Code ist durch alle Teammitglieder verteilt. Den ganzen Verlauf der Datei ist bei jedem System verfügbar. Es gibt immer noch eine Hauptkopie des Codes aber sie wird bei einem Client gespeichert, statt bei einem Server. Es ist nach diesem Weg nicht möglich, Code Schnipseln zu sperren. Deswegen können Entwicklern Änderungen bei ihren lokalen Kopien und, wenn sie fertig sind, durch eine Anfrage an den Besitzer der Hauptkopie, seine Änderungen integrieren lassen. Schlussendlich ist eine Version des Projektes, nur eine Sammlung von Änderungen in der Hauptkopie.

Git

Git ist eine den beliebten Versionierung Tools.

Commits

In Git, sind Commits die Gundlage einer Repository (Das Ding, die den ganzen Sourcecode und Verlauf derselben beinhaltet). Einen Commit besteht aus einer Sammlung von Änderungen (bzw. hin gefügte und gelöschte Code).

Snapshots

Der wichtigste Unterschied zwischen Git und andere VCS ist, dass Git kontrolliert mehrere Versionen eines Projektes. Das heisst, das Git mehrere Kopien denselben Dateien speichert, nach jedem Commit. Meisten VCS speichern alle Änderungen und können, damit die jetzige Version des Projektes, durch den Verlauf abbilden.

Befehle sind meisten Lokal ausgeführt

Meisten Befehle sind nicht von remote Files abhängig. Falls ihr gewöhnt sind mit CVCS zu arbeiten, wisst ihr, dass es immer Latenz zwischen jedem Befehl gibt. Da den ganzen Verlauf des Projektes sich lokal auf ihrem Rechner findet, werden alle Befehle mit höhen Effizient ausgeführt. Das erlaubt die Bearbeitung von Dateien, wenn man offline ist.

Git hat Integrität

Git speichert Daten in einem sogenannten «Content-addressable file system». Das bedeutet, dass Git speichert alles mit einem einfachen «key-value» System. Wenn man Inhalt in einer Repository hin fügt, gibt Git einen «unique identifier» zurück. Damit können alle gespeicherten Daten wiedergeholt werden. Git benutzt SHA-1 für die Generierung von UIDs.

Git kann (normalerweise) nur hinzufügen

Fast alle Befehle von Git werden für die Addierung von Daten gebraucht. Es ist sehr kompliziert Änderungen zu machen, die nicht zurückkehrbar sind. Man kann mit wenig Aufmerksamkeit Änderungen löschen oder verlieren, aber nachdem eine Snapshot beim Git commited worden ist, ist es praktisch unmöglich diese zu verlieren.

Branches (Zweige)

Einen Commit zeigt immer auf seinen «Parent Commit» und auf eine Snapshot seinem Inhalt. Mit diesem System ist es möglich, dass einen Commit mehrere «Children» hat. In diesem Fall wurde eine Kette (Zweige) von Commits in zwei verschiedene Verläufe aufteilen. Entwicklern können nun auf zwei verschiedene Verläufe des Projektes arbeiten und sie später zusammenfügen.

C#: Async

Asynchrone Programmierung ist ein Weg, um Leistungsengpässe und die Reaktionsfähigkeit einer Anwendung zu verbessern. Es kann aber sehr kompliziert werden, eine Applikation zu schreiben, debuggen und verwalten.

Wenn die C# Version 5 herausgekommen ist, ist eine sehr einfache Ansatz eingeführt worden, die sehr viele komplizierte Arbeit an den Compiler weitergibt und dem Entwickler Zeit und Geduld erspart.

Asynchronie wird für potenziell blockierende Tasks gebraucht, wie z.B. Webzugriff oder Laden eines Files. Wenn diese Aktivitäten in einer synchronen Applikation aufgerufen werden, wird die ganze Anwendung auf diesem Prozess warten, bis sie weiterlaufen kann.

Es gibt mehrere Anwendungsbereiche wo asynchrone Programmierung Sinn machen:

  • Webzugriff
  • Arbeiten mit Dateien
  • Arbeiten mit Bildern

Mit der Hilfe von Asynchronie, können Applikationen solche Funktionen ausführen und gleichzeitig auf Benutzer Input reagieren.

Es gibt zwei Schlüsselwörter in C#, await und async, die bei asynchroner Programmierung gebraucht werden. Diese beiden Schlüsselworte werden gebraucht, um Async-Methoden zu definieren.

Man kann eine asynchrone Methode so definieren:

async Task <method_name>() { }

Diese Methode kann jetzt asynchron aufgerufen werden und in seinem eigenen Thread laufen. Die Klasse Task ist eine spezielle Klasse die für die Verwaltung alle Tasks/Aufträge. Mit dieser Klasse, kann eine asynchrone Methode sagen, wenn sie ihren Auftrag erledigt hat.

Mit der Verwendung von der Schlüsselwort await kann eine asynchrone Methode auf eine andere asynchrone Methode warten. Sobald eine await aufgerufen wird, wird die Methode angehalten, und die Steuerung kehr zum Aufrufer der Methode zurück.

Ablauf

Async Task<int> AccessTheWebAsync()<-1.
{
  HttpClient client = new HttpClient();
  
  Task<string>getStringTask = client.GetStringAsync(«http://storage.freestrings.com»);<-2.
  
  DoIndependentWork();<-3.

  string urlContents = await getStringTask;<-5

  return urlContents.Length; <-6
}

void DoInpendentWork()
{
  resultsTextBox.Text += «Working…\r\n»;<-4.
}
  1. Die Methode wird aufgerufen und den Aufrufer dieser Methode wartet auf sie.
  2. Die Methode «AccessTheWebAsync» erstellt eine Instanz des HttpClient und ruft die asynchrone Methode «GetStringAsync» auf. In «GetStringAsync» wird etwas gemacht, das die Ausführung der Methode anhalten wird. Es müsste gewartet werden, bis den Text heruntergeladen würde. Umso Sachen zu vermeiden, übergibt die «GetStringAsync» Methode die Steuerung an ihren Aufrufer «AccessTheWebAsync».
  3. Da «getStringTask» noch nicht fertig ist, kann «AccessTheWebAsync» seiner Arbeit fortfahren, die nicht vom Ergebnis der «GetStringAsync» abhängig ist. Diese Aufgabe ist «DoIndependentWork» die eine synchrone Methode ist.
  4. «DoIndependetWork» ist eine synchrone Methode und führt ihrer Aufgabe aus. Erst wenn diese Methode fertig ist, wird die Steuerung an den Aufrufer «AccessTheWebAsync» zurückgegeben.
  5. Bei diesem Punkt, brauchte die Methode «AccessTheWebAsync», das Ergebnis von «getStringTask», um mit ihrer Arbeit fortfahren zu können. Mit Hilfe der await Schlüsselwort, kann «AccessTheWebAsync» die Steuerung an ihrem Aufrufer zurückgeben und sicherlich auf das Ergebnis von «getStringTask» warten.
  6. Danach kann die Methode «AccessTheWebAsync» ihrer Arbeit abschliessen und den erwarteten Wert zurückgeben.

IEnumerable Interface

Die IEnumerable Interface ist eine sehr hilfreiche Funktionalität des .NET Frameworks. Sehr oft musst man durch eine Collection von Objekten iterieren und IEnumerable erlaubt das und macht unser Leben viel einfacher.

Die IEnumerable Interface definiert eine Methode GetEnumerator, die eine IEnumerator Interface zurückgibt. Eine Collection, die IEnumerable implementiert kann in einem for-each Loop gebraucht werden.

Wichtigste Punkte:

– Die IEnumerable Interface befinden sich in der System.Collections.Generic Namespace.

– Die IEnumerable Interface ist ein generisches Interface und erlaubt Iterationen durch generische und nicht generische Listen.

– Man kann linq Query Expressions mit diesem Interface brauchen.

– Dieses Interface gibt einen Enumerator zurück, den durch eine Collection iteriert.

So kann man dieses Interface implementieren:

public class MyIterableCollection : IEnumerable
{
       public IEnumerator GetEnumerator()
       {
             (…Code…)
       }
}

 

Die IEnumerator Interface

Die IEnumerator Interface hilft und durch die Elemente eine Collection zu navigieren. Dieses Interface hat die folgenden Methoden:

– MoveNext()

– Reset()

MoveNext()

Diese Methode ändert den Wert des Enumerators auf dem nächsten Element der Collection und gibt einen Boolean Wert zurück. Die Methode gibt True zurück falls den Enumerator ohne Fehler auf dem nächsten Element gesetzt worden ist und False falls den Enumerator auf keinem neuen Element zeigen kann, bzw. befindet er sich am Ende der Collection.

Reset()

Die Reset Methode setzt den Wert des Enumerators auf seiner ersten Position, die erste Position befindet sich vor dem ersten Element der Collection.

Das IEnumerator Interface hat eine Property die Current heisst und gibt den Wert des jetzigen Elements zurück.

So kann man das Interface implementieren:

public class MyEnumerator : IEnumerator
{
       public object Current
       {
             get { (…Code…) }
       }

       public bool MoveNext()
       {
            (…Code…)
       }

       public void Reset()
       {
            (…Code…)
       }
}

 

Hier ist ein kleines Beispiel, wie man dieses Interface brauchen könnte:

// Einfaches Objekt für unsere Collection
public class Musician
{
     public Musician(string name, string song)
     {
        Name = name;
        Song = song;
     }

     public string Name { get; private set; }
     public string Song { get; private set; }
}

// Eine Collection von unsere Musicians Klasse
// Diese Collection implementiert IEnumerable 
// damit sie in einem for-each loop gebraucht
// werden kann
public class Collaboration : IEnumerable
{
    private Musician[] _musicians;

    public Collaboration(Musician[] musiciansArray)
    {
        _musicians = new Musician[musiciansArray.Length];

        for(int i = 0; i < musiciansArray.Length; i++)
        {
            _musicians[i] = musiciansArray[i];
        }
    }

    // Implementation der GetEnumerator Methode
    IEnumerator IEnumerable.GetEnumerator()
    {
        return (IEnumerator)GetEnumerator();
    }

    public MusiciansEnumerator GetEnumerator()
    {
        return new MusiciansEnumerator(_musicians);
    }
}

// Wenn man IEnumerable implementiert, braucht es auch eine IEnumerator Klasse
public class MusiciansEnumerator : IEnumerator
{
    private Musician[] _musicians;

   // Enumerators fangen immer vor dem ersten Element an
    // bis die Methode MoveNext() aufgerufen wird
    private int _position = -1;

    public MusiciansEnumerator(Musician[] musicians)
    {
        _musicians = musicians;
    }

    object IEnumerator.Current => Current;

    public Musician Current
    {
        get
        {
            try
            {
                return _musicians[_position];
            } catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }

    public bool MoveNext()
    {
        _position++;
        return (_position < _musicians.Length);
    }

    public void Reset()
    {
        _position = -1;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Musician[] musiciansArray = new Musician[3]
        {
            new Musician("Freddie Mercury", "Bohemian Rapsody"),
            new Musician("Michael Jackson", "Thriller"),
            new Musician("John Legend", "All of me")
        };

        Collaboration collab = new Collaboration(musiciansArray);

        foreach (var musician in collab)
        {
            Console.WriteLine($"{musician.Name} - famous for: {musician.Song}");
        }

        Console.Read();
    }
}

/*
* Die Ausgabe für diesen Code ist:
* 
* Freddie Mercury - famous for: Bohemian Rapsody
* Michael Jackson - famous for: Thriller
* John Legend - famous for: All of me
* 
*/

 

REST API

Web API

Eine API ist eine Application Programming Interface, bei einem Web Server oder Web Browser verwendet wird. Eine Web API dient dafür, dass man Dienste einer Web Applikation in einem anderen Programm verwenden kann. Web API werden mit HTTP Anfragen verwendet. Normalerweise schickt man eine Anfrage mit JSON Syntax aber meisten APIs unterstützen auch XML und anderen Formaten.

REST Eigenschaften

Eine REST API ist eine Web API die bestimmten Eigenschaften hat. Diese Eigenschaften erleichtern die Benutzung einer API für den Benutzer und für den Server. Durch diese Eigenschaften werden die folgenden Punkte verbessert:

  • Bessere Performance zwischen verschiedene Komponente und effiziente Netzwerk.
  • Skalierung von den Anzahl Interaktionen zwischen alle Komponente. Das erlaubt, dass man mehr leisten kann.
  • Simplizität für alle Benutzern.
  • Kommunikation zwischen alle Komponente einer API wird mehr transparent.

REST Regeln

Die sechs Regeln einer REST API dienen dafür man alle Entstehung allen Eigenschaften garantieren kann. Die Regeln sind:

Client-Server Architektur

Der Unterschied zwischen Client und Server Kapazitäten sollen möglichst gut erkennbar sein, damit alle Client Komponente bei mehreren Plattformen gebraucht werden können.

Statelessness

Statelessness heisst, dass keine mehrfachen Interaktionen von der Benutzerseite gebraucht werden, um einen Request zu bauen. Alle Daten, die für einen Request wichtig sind, sollen vom Benutzer erhalten werden und den Server darf keine Daten zwischen Request halten. Es ist aber erlaubt die Daten aus den Requests in einer Datenbank zu speichern falls, das Ziel etwas persistent zu Speichern ist.

Cacheability

Antworten einem Request (normalerweise HTML oder JSON Textkörper) sollen explizit oder implizit als speicherbar definiert werden. Dies erlaubt eine schnellere Interaktion zwischen Client und Server.

Layered System

Das heisst, dass den Client nicht merken soll, ob er den Requests direkt an den End Server schickt. Falls es anderen Servers zwischen Client und End Server gibt, kann die Skalierung vereinfacht werden und die Leistung der API erhöhen.

Uniform Interface

Ressourcen Identification in Requests

Ressourcen müssen identifiziert werden in jedem Request, durch den Gebrauch von URIs. Die Ressourcen lassen sich von der Antwort zu dem Client gut Unterscheiden durch HTML und JSON.

Ressourcen Manipulation durch Repräsentationen

Wenn den Client eine Antwort von Server bekommt, muss er genug Information (inklusiv Metadaten) über eine Ressource erhalten, um dieselbe ändern oder löschen können.

Hypermedia as the engine of application state (HATEOAS)

Wenn den Client einen initialen URI, um die REST Applikation zu dienen, gebraucht hat, muss den Server den Client durch Hyperlinks, alle möglichen Funktionalitäten und Navigation geben.

HTTP Request Methoden

Es gibt verschiedene Request Methoden, die man brauchen kann. GET ist eine sichere Methode die nur Informationen über eine oder mehrere Ressourcen zurückgibt. PUT ist nicht sicher, da es eine Ressource ersetzt. PATCH kann eine Ressource ändern ohne, dass man alles ersetzen muss. POST erstellt eine neue Ressource. DELETE löscht eine Ressource.

Unity Game Engine

Die Unity Game Engine ist einen IDE, der für die Erstellung und Entwicklung von Games und andere interaktive Medien gebraucht wird. Unity ist meistens von Indie Entwicklern gebraucht und hat eine sehr freundliche Lernkurve. Es ist einfach Beginner Projekte zu erstellen und die Basics von Unity lassen sich von mehreren Tutorials einfach erklären.

 

Geschichte

Die Idee für die Unity Game Engine, kam von Nicholas Francis, Joachim Ante und David Helgason. Die drei Entwickler wollten, am Anfang, Games zusammen entwickeln aber sie haben später ein grösseres Interesse an einem Tool, mit dem man Games entwickeln kann, gefunden. Danach haben sie angefangen die Unity Game Engine in einem Keller in Kopenhagen zu entwickeln. Am Anfang ist die Unity Game Engine nur für MAC OS entwickelt worden aber später haben die Hersteller, der Unity Game Engine, diese auch für Windows und Web verbreitet. In den nächste paar Jahren, ist die Interesse an Web Browser Games sehr hoch gewesen und die Entwickler der Unity Game Engine haben sich auf dieser Plattform fokussiert. Nach zwei Jahren haben sie ihr Ziel erreicht aber mussten noch ein Game entwickeln, damit sie die Stärken von Unity zeigen könnten. Danach ist der ersten Unity Game zusammen mit der Unity Game Engine, am 6. Juni 2005 auf der Welt gekommen. Mit der Zeit sind Handy Games sehr beliebt worden und Unity hat sich auch auf die Handy Plattform verbreitet. Solang die Gaming Industrie sich immer weiterentwickelt hat und mehr Hardware erstellt war, hat sich Unity auch entwickelt. Heutzutage gibt es viele Menschen, die die Engine benutzen und es gibt eine grosse Liste von Games, die mit Unity entwickelt worden sind. Jetzt kann Unity Games für 27 verschiedene Plattformen exportieren und die Engine kann auch für Animationen und Datendarstellung gebraucht.

 

Skript Sprachen

Unity erlaubt, dass andere Anwendungen und Hardware an sich angepasst werden. Die Programmiersprachen, die von Unity unterstützt werden sind folgende:

UnityScript:

UnityScript ist fast dasselbe wie JavaScript aber ist für Unity eingerichtet worden. UnityScript ist sehr einfach zu lernen und ist für Anfänger empfohlen. UnityScript ist sehr schnell zu schreiben und alle Type Casting wird im Hintergrund gemacht. Da diese Sprache sich an JavaScript ähnelt, hat sie auch die Vorteil Klassen und Vererbung programmieren zu können.

C#:

Ist viel schwieriger als UnityScript und man muss viel mehr schreiben, um sein Ziel zu erreichen. Den Compiler handelt auch nicht viel Logik und es muss alles explizit codiert werden.

Boo:

Boo hat die gleiche Syntax wie Python und ist ähnlich wie UnityScript strukturiert. Da so wenig Menschen diese Sprache verwenden, ist Support dafür auch sehr selten.

C# Features 2

Wie im letzten Blogpost, werde ich die Features den letzten Versionen C# dokumentieren. Im letzten Blogpost habe ich einige Features der Version 3.0 und eine aus der Version 6.0 (statische Importe). In diesem Blogpost will ich über die Version 5.0, 6.0 und 7.0 schreiben.

Version 5.0

  • Asynchrone Methoden

Die Version 5.0 hat asynchrone Methoden zu C# gebracht. Asynchrone Methoden sind heutzutage sehr hilfreich für einen Entwickler und die C# Implementation ist sehr praktisch zu benutzen. Asynchrone Methoden sollen immer benutzt werden, um ein Programm flexibel zu machen und Responsiveness zu garantieren. Stellen Sie sich vor, dass Sie ein Programm schreiben, das einen UI hat und Daten verarbeiten kann, wenn es Input des Benutzers bekommt. Wenn es die Daten einfach nach einem Input verarbeiten würde, wäre die UI blockiert bis die Daten verarbeiten worden sind. Dafür können wir eine asynchrone Methode brauchen. Diese Methoden verwenden «Task» und «Task». Diese Tasks sind wie unabhängige Threads. Mit dem «async» Schlüsselwort» kann eine Methode in eine asynchrone Methode umgewandelt werden. Mit dem «await» Schlüsselwort weiss eine asynchrone Methode, dass sie die Steuerung an den Aufrufen zurückgeben muss. Den Code für unseren Beispiel würde ungefähr so aussehen:

submitButton.Clicked += async (o, e) =>
{
  // In dieser Methode werden wir definieren, dass es einen

  // separate Task starten muss, um unseren async
  // MakeCalculationsAsync() Methode auszuführen. Wichtig
  // ist es, dass MakeCalculationsAsync()
  // eine Task oder Task zurück gibt.

  var output = await MakeCalculationsAsync(input);
};

Wenn wir das so programmieren, wird das UI immer noch verwendbar sein, obwohl die Daten immer noch verarbeitet werden. Es ist auch einfacher als Threads zu konfigurieren und initialisieren.

 

  • Aufrufer Informationen

Die Aufrufer Informationen können für das Debuggen sehr hilfreich sein. Die Aufrufer Informationen können in einer Methode als Parametern Attribute definiert werden. Die drei vorgegebenen Informationen sind die «CallerFilePathAttribute» (string), «CallerLineNumberAttribute» (int) und «CallerMemberNameAttribute» (string).

public void DoProcessing()
{
  TraceMessage("Something happened.");
}

public void TraceMessage(string message,
  [System.Runtime.CompilerServices.CallerMemberName] string memberName = "",
  [System.Runtime.CompilerServices.CallerFilePath] string sourceFilePath = "",
  [System.Runtime.CompilerServices.CallerLineNumber] int sourceLineNumber = 0)
{
  System.Diagnostics.Trace.WriteLine("message: " + message);
  System.Diagnostics.Trace.WriteLine("member name: " + memberName);
  System.Diagnostics.Trace.WriteLine("source file path: " + sourceFilePath);
  System.Diagnostics.Trace.WriteLine("source line number: " + sourceLineNumber);
}

// Sample Output:
//  message: Something happened.
//  member name: DoProcessing
//  source file path: c:\Visual Studio Projects\CallerInfoCS\CallerInfoCS\Form1.cs
//  source line number: 31

(Beispiel vom: https://docs.microsoft.com/de-de/dotnet/csharp/programming-guide/concepts/caller-information)

 

  • Ausdruckskörpermember

Properties haben Upgrades bekommen und man kann viel mehr machen. Jetzt kann man Properties initialisieren. Die initialisierte Properties funktionieren immer noch gleich aber jetzt braucht man zum Beispiel keine private Variabel um eine read-only Variabel zu definieren.

public string Name { get; } = "A Name";

Mit einer Art von Lambda Expression kann man die Get Methode definieren. Diese Ausdruckskörpermember sind sehr gut, um code zu vereinfachen.

public string Name => "John" + ". " + "Doe";

C# Features

C# ist schon eine alte Programmiersprache aber es entwickelt sich immer weiter und jede neue C# Version zeigt, dass C# sehr spezielle Eigenschaften hat, die sich von anderen Programmiersprachen unterscheiden. Ab die Version 3.0 ist C# sich als einer den wichtigsten Programmiersprachen erkannt worden, da es neue und originale Features gebracht hat. Einige diesen Features sind sehr gut für die Umstellung von Code und besser Übersichtlichkeit, andere Features sind sehr wichtig für meisten C# Programme heutzutage, da sie eine sehr starke Funktionalität haben.

Version 3.0

Die Version 3.0 hat LINQ eingeführt und ist eine der wichtigsten und praktische Eigenschaften von C#. LINQ steht für Language-Integrated Query und es erlaubt, dass Abfragen für die Daten eines Programmes abgefragt werden können. Mit LINQ kann man aus einer Collection bestimmte Werte zu holen. Es funktioniert ähnlich wie eine SQL Abfrage aber die Syntax ist ein Bisschen verschieden. Eine LINQ Expression (Abfrage) sieht folgendes aus:

from <abgefragte_variable > in <collection_name>

            where <bedienung>

            select <wert_aus_abfrage>;

LINQ hat mehrere Funktionalitäten wie ‘orderby’ und ‘groupby’, die gleich wie bei SQL funktionieren.

Eine Funktionalität, die auch sehr praktisch ist, ist Anonyme Typen. Anonyme Typen sind Objekte, die nicht explizit deklariert sein müssen. Es funktioniert ähnlich wie eine «var» Zuweisung aber die Anonyme Typen sind für Objekte und das bedeutet, dass man einen Objekt Initialisieren muss und den Compiler wird für dieser nicht vordefiniertes Objekt, die richtige Referenz zuweisen. Meisten Anonyme Typen werden so deklariert:

var anonymous = new { <property_name> = <wert>, … };

Die linke Seite dieser Expression ist eine anonyme Deklaration, die den Compiler erklärt, dass er den Typ für dieses Objekt selbst identifizieren muss. Meistens ist dieser Typ immer «object». Die rechte Seite ist eine Initialisierung eines Objektes. Mit die «new» Keyword wird ein neues Objekt erstellt und in den geschweiften Klammern werden alle Properties definiert und auf einen Wert zugewiesen.

Erweiterungsmethoden sind Methoden, die einen Objekt erweitern können und ist auch eine den eigenartigen Eigenschaften von C#. Einen Erweiterungsmethode muss das Objekt zum Erweitern als Parameter deklarieren und das Keyword «this» muss auch vorhanden sein.

public static <methoden­­_name> (this <objekt_zum_erweitern> <parameter_name>) { … }

  • Die Methode muss immer statisch sein, damit das erweitertes Objekt Zugriff hat. Diese Methoden sind sehr praktisch, wenn ein vorgegebenes Objekt (z.B. string) geändert sein muss. Wenn man <objekt_zum_erweitern> mit string ersetzt, können alle string Objekt diese Methode brauchen.

Der nameof Operator ist auch einen Operator, der die Vermeidung von Typfehler und Bugs erlaubt. Mit diesem Operator kann man den Namen einer Variablen erzeugen ohne einen String selbst zu schreiben. nameof(<variable>) Gibt einen String zurück mit dem Namen der vorgegebene Variable.

Eine leicht unnötige aber trotzdem praktische Feature ist der Statische Import. Wenn man eine Methode eines anderes Namespaces erzeugen muss. Kann man den Importieren ohne den ganzen Namespace zu schreiben. Bei der Imports Liste kann man
using static <namespace>; schreiben und die Methoden verwenden in diesem Namespace. Zum Beispiel statt Console.WriteLineHello»); kann man es vereinfachen mit:

using static Windows.System.Console;

WriteLineHello»);