Mehr von Jürgen Gutsch

Mehr von Jürgen Gutsch

Empfehlungen von Jürgen Gutsch

Blog-Empfehlungen von Jürgen Gutsch

Willkommen bei ASP.NET Zone. Anmelden | Registrieren | Hilfe

Jürgen Gutsch

ASP.NET und mehr...
Dependency Injection, ASP.NET MVC 4 und Ninject

Einleitung

Eine Einführung in die Problematik und einen kurzen Überblick über IoC-Container habe ich in folgendem Blogbeitrag bereits niedergeschrieben: Dependency Injection, ASP.NET MVC 4 und Autofac. Den Teil lasse ich hier also weg, da es um dasselbe Thema geht, nur mit einem anderen IoC-Container.

Ninject

Ninject brüstet sich damit einer der einfachsten IoC-Container zu sein.

Ninject: An obsessive focus on simplicity and ease of use.

Dieses und der kleine Ninja als Logo machen Ninject interessant. Aber auch ein anderer Aspekt sollte nicht ignoriert werden: sucht man per NuGet nach Ninject, findet man einige zugehörige Packages, die auf eine große Community und umfangreichen Support schließen lassen. Die Zahlen auf StackOverflow beweisen dass: 1,779 Fragen die mit “Ninject” getagt worden sind.

Somit ist ein eventuelles Risiko durch fehlenden Support fast ausgeschlossen.

DI mit MVC

Das erste was hier auffällt, wenn man nach per NuGet nach Ninject sucht, ist das fehlende  Package für MVC4. Es gibt nur das Package Ninject.MVC3, das allerdings ebenso mit MVC4 funktioniert und getrost installiert werden kann.

Nach der Installation des MVC3 Packages per NuGet, wird auch Ninject und Ninject.Web.Core installiert und im Ordner “App_Start” wird zudem die Datei NinjectWebCommon.cs abgelegt, die für die gesamte Konfiguration des IoC-Containers verantwortlich ist. Die IocConfig.cs wie sie im letzten Beitrag nötig war, entfällt hier also.

Die Test-Anwendung die ich im Beitrag Dependency Injection, ASP.NET MVC 4 und Autofac erstellt hatte, war in wenigen Minuten umgeschrieben. Die Registrierungen des UnitOfWork und des generischen Repositories waren schnell in die NinjectWebCommon.cs übernommen. Hierfür wurde die Methode “RegisterServices” vorgesehen:

private static void RegisterServices(IKernel kernel)
{
    kernel.Bind(typeof(IRepository<>)).To(typeof(Repository<>));
    kernel.Bind<IUnitOfWork>().To<UnitOfWork>();
}

Alle zusätzlichen Registrierungen die für Autofac noch nötig waren, können weggelassen werden, da sie scheinbar schon in den Ninject-Bibliotheken fest hinterlegt sind. Man kann das durchaus als Vereinfachung sehen. Sollten eigene ModelBinderprovider oder ActionBilderProvider nötig sein, so darf ich auf das Beispiel von K. Scott Allen verweisen: Injectable, Configurable Action Filters

Weitere IoC-Container

In weiteren Beiträgen zeige ich die Konfiguration von folgenden weiteren IoC-Containern anhand des selben Szenarios:

  • Autofac
  • LightCore
  • Unity
  • NInject
  • StructureMap
  • Castle Windsor
Ich bin .NET-Entwickler und ich teste meinen Code nicht!

So oder so ähnlich muss es sich für einen Java-Entwicklers anhören, wenn er sich mit einem .NET-Entwickler über Unit-Tests und Continous Integration unterhält. (Mag sein, dass nicht jeder Java-Entwickler guten Code schreibt, aber zumindest diejenigen mit denen ich mich unterhalten konnte und deren Code ich sehen durfte.)

Beim letzten CyberTreff habe ich mich wieder mal mit einem Java-Entwickler unterhalten dürfen, der mich unter anderem auch fragte, ob es richtig sei, dass in der .NET-Welt Unit-Tests und Continous Integration nicht üblich sei. Leider musste ich die Frage mit “Ja” beantworten. Es ist tatsächlich nicht üblich! Auch wenn es eine ganze Menge guter .NET-Entwickler gibt, die diese Techniken verinnerlicht haben.

Zumindest ist es meine Beobachtung die ich in den letzten Jahren machen durfte.

  • Unit-Testen wird als zu aufwendig / teuer angesehen
  • Unit-Testen wird als unnötig angesehen
  • Unit-Testen wird als unnötige Philosophie angesehen.
  • Continous Integration ist nicht bekannt
  • CI wird als zu aufwendig / teuer angesehen
  • Man beschränkt sich auf Nightly Builds
  • Man baut auf der Maschine vom Chef
  • Jeder Entwickler baut auf seiner Maschine

Warum ist das in der .NET-Welt so? (<= Pauschalisiert. Möglicherweise auch in anderen Sprach-Welten)

Ich führe es hauptsächlich auf die unterschiedlichen sprachlichen Ursprünge der .NET-Entwickler zurück. Fehlendes Tooling im VB6 und VisualC++ sind mit Sicherheit eine Ursache für das fehlende Verständnis für Test- und Build-Automatisierung. Hinzu kommen “konvertierte” Java-Entwickler, Delphi, FoxPro, Lotus Notes, etc. Es entsteht ein Mix aus verschiedensten Techniken, Philosophien, Einstellungen und Vorgehensweisen. Hinzu kommt dass es kaum engstirnigere Menschen gibt wie Softwareentwickler, [Humor]von Pädagogen mal abgesehen.[/Humor]

Wie kann man das unter einen Hut bringen?
Wie schafft man es, das alle eine Sprache sprechen und auf die gleiche Art Software entwickeln?

Die Clean Code Developer Initiative, liefert mit ihrer “Formelsammlung” einen Ansatz, der allerdings auch nur diejenigen erreicht, die sich sowieso über die “üblichen” Informationskanäle fortbilden.

Wie schafft man es nun, dass diese Techniken die in anderen Technologien selbstverständlich sind auch in der .NET-Welt selbstverständlich sind?

Ich sehe mehrere Möglichkeiten, wobei eine von der CCD schon präferiert wird: CCD empfiehlt einfach es einfach zu tun. Einfach machen und die “anderen”-Entwickler die Vorteile spüren und sehen lassen. Das ist gut, sogar sehr gut, ABER:

  • Ich kennen auch Entwickler, denen es explizit untersagt wurde Unit-Tests zu schreiben. Diese hochmotivierten Leute resignieren irgendwann.
  • Dieser Prozess ist auch recht langsam.

Eine weitere Möglichkeit ist Geld. Geld zieht immer und hat fast immer Prio 1:

Abgesehen davon dass man bei einem Broken Build 50 Cent für die Kaffeekasse verlangen könnte, muss den Verantwortlichen vorgerechnet werden wie viel Zeit mit Unit-Tests (am besten Test-First) und Continous Integration gespart werden kann.

Ohne Unit-Tests rechne ich für ein Feature etwa die Hälfte der Zeit für Bug-Fixing ein. Ich denke das ist ein guter Mittelwert, manche Bugs sind sicher schneller gefunden, manche dauern länger. Bugs die älter sind haben möglicherweise schon einen gewissen Supportaufwand verursacht. Benötige ich also für ein Feature 10 Tage, so muss ich mit 5 Tagen für Support und Bugfixing rechnen. Das ist eine ganze Menge Geld. ;-)

Mit Unit-Tests benötigen wir für das gleiche Feature für die Implementierung möglicherweise etwas länger. (Üblicherweise beschleunigen Unit-Tests sogar die Implementierung, mehr dazu später). Sagen wir also wir arbeiten mit Tests-First und benötigen nun 11 Tage für das Feature. Durch die Absicherung per Tests werden viele Bugs schon während der Implementierung gefunden. Und die die Durchrutschen? Werden durch Unit-Tests schneller lokalisiert und behoben. Der Aufwand im Nachhinein, abgesehen vom Support geht gegen 0. Ich behaupte jetzt also Wir haben einen Gesamtaufwand von 13 Tagen. Das sind zwei Tage weniger als ohne Unit-Tests.

Tests müssen von Entwickler ausgeführt werden. Wenn er das nicht macht, sollte das zusätzlich ein Automatismus tun. Hier kommt Continous Integration ins Spiel. Ein Build-Server holt sich automatisch die Codes, baut die Software und führt ALLE Tests aus. Und das immer dann, wenn neuer Code zur Verfügung steht. Der Entwickler bekommt innerhalb von zehn Minuten ein Feedback über seine Arbeit und kann eventuelle Probleme umgehend beheben. Ich reduziere damit den Aufwand des obigen Features um einen weiteren Tag. Es bleiben also 12 Tage für das Feature.

So, und jetzt beschleunigen wie die Implementationszeit mit Unit-Tests: Wir alle, die mit VB6 gearbeitet haben, kennen die altbewährte Technik der “F5 getriebenen Entwicklung”. Code schreiben, F5 drücken, ausprobieren, Code anpassen und wieder F5, und so weiter. Diese Technik wird leider immer noch sehr häufig genutzt. Und wer hat nicht schon ein Stück Code debuggen wollen, das sich im letzten, hinteren Eck der Anwendung versteckt und man sich erst 5 fünf Minuten durch den Prozess der Anwendung klicken muss? Hat man dann den Fehler gefunden und behoben geht das wieder von vorne los um den Fix zu testen. Kennen wir alle. Aber kennen wir auch alle die Möglichkeit, dass uns ein Unit-Test helfen kann diese Code-Stelle schneller zu erreichen? Ganz genau: Wir können im Code das zu testende Modul Instanzieren (müssen ggf. noch einen Kontext herstellen) und die zu testende Methode mehr oder weniger direkt ansprechen. Ist der Unit-Test einmal erstellt, müssen wir ihn nicht nochmal erstellen und können ihn jedes Mal aufs Neue nutzen um zu debuggen. Etwas Refactoring am Test und wir haben Tests, die wir sogar automatisiert ausführen lassen können. Mit dieser Variante verringern wir den Implementationsaufwand um – sagen wir mal pessimistisch – zwei Tage und der endgültige Aufwand (inklusive Support und Bugfixing) liegt nun bei 10 Tagen.

Klasse oder? Wir sparen somit 5 Tage an Aufwand :-)

Klar ist die Rechnung etwas pauschalisiert, entspricht aber ungefähr meinen Beobachtungen und mir geht es hier ums Prinzip. Die Vorteile von testgetriebener Entwicklung ist keine philosophische Diskussion, sondern eine Tatsache die sich auf das Budget auswirken kann.

Es gibt weitere Methoden den Aufwand zu verringern, die nicht ganz so offensichtlich sind oder sich langfristiger auswirken:

  • Pair Programming
  • Code Reviews
  • Code Generierung
  • Verbesserung der Code Qualität
  • Regelmäßige Übungen, z. B: per Coding-Dojos
  • Fortbildung

Achtung Werbung: By the Way unterstütze ich Unternehmen gerne bei der Steigerung der Entwicklungs-Performance und der Software-Qualität mit entsprechenden Beratungen und Schulungen

Jede Ausrede sich gegen Unit-Tests und Continous Integration zu entscheiden lasse ich persönlich nicht durchgehen. Für mich ist das Netz und doppelter Boden ohne die ich Software nur ungern und mit schlechtem Gefühl im Magen herausgebe. Zumindest im Team mit unterschiedlichen Wissens- und Kenntnisständen sind diese Techniken ein MUSS um das Funktionieren der Software zu gewährleisten.

Hier ein scheinbar übliches Scenario:

Chef: Bist du fertig?
Dev: Ja.
Chef: Funktioniert auch alles?
Dev: Ja.
Chef: Hast du auch getestet?
Dev: Ja.
Chef: (eine Stunde später) Wie testest du denn? Ich habe noch drei Fehler gefunden. Da funktioniert Garnichts...
Dev: Bei mir tut’s aber.

Wäre es so nicht schöner?

Chef: Bist du fertig?
Dev: Ja, funktioniert alles wie gefordert. Hier ist der Testbericht
Chef: (eine Stunde später) OK. Hier sind drei neue Anforderungen. Kannst du das umsetzen?

Ich als Softwareentwickler möchte komplexe Logiken durch Tests vor Änderungen und anderen äußeren Einflüssen abgesichert haben. Ich möchte genauso beweisen können, dass meine Umsetzung alle Kriterien erfüllt. Das ist mit Unit-Tests machbar.

XML parsen mit jQuery

Wenn jQuery DOM kann ist es egal ob es sich um HTML oder XML handelt. Das habe ich letzte Woche festgestellt, als es darum ging XML (leider kein JSON) vom Server zu laden und zu interpretieren.

So viel Lektüre gibt es zu dem Thema noch nicht, weswegen ich davon ausgehe, dass hier durchaus auf Interesse stoßen kann :-)

Also jQuery kann nicht nur HTML sondern auch XML. Das interessante dabei ist, dass nicht per XPath durch die elemente navigiert, sondern durchaus mit den gewohnten jQuery Selektoren arbeiten kann.

Folgender kleiner Ajax-Aufruf holt mir die XML-Daten von einer angegebenen URL:

$.ajax({
    url: url,
    success: function (xml) {
        setTitle(xml);
        setContent(result);
    }
});

in der Methode setTitle greife ich dann per jQuery-Selector auf den wert zu der mir als Titel ausgegeben werden soll:

function setTitle(xml) {
    var title = $(xml).find('menuname').text();
    $('#header').text(title);
}

mit dem Aufruf von $(xml) erzeuge ich ein jQuery-DOM-Objekt der XML-Daten die hier als String zur Verfügung stehen. über die Methode find('menuname') hole ich mir das Objekt des “menuname”-Tags um dann den Inhalt auszulesen.

Im folgenden (nicht ganz schönen) Konstrukt iteriere ich durch eine Anzahl von “element”-Tags um dann auch auf deren Attribute zuzugreifen:

$(xml).find('element').each(function () {
    var type = $(this).attr('type');
    if (type === "paragraph") {
        result += $(this).find('text').text();
    }
    if (type === "image") {
        var imageValue = $(this).find('picture').text();
        result += '<image src="' + imageValue + '">';
    }
});

Wie man sieht, sind das tatsächlich die klassischen jQuery-Methoden die hier verwendet werden. Ein umständliches Umwandeln in JSON ist für einfache kleine Datenmengen auf diese Art nicht notwendig. Nochweniger muss auf XMLHTTP oder XMLDOM zurückgefriffen werden um sich mühsam durch den DOM zu hangeln.

Selbstverständlich sind auch etwas komplexere Selektoren möglich:

$(xml).find('page containers container[name=content] elements element').each(function(){
    //
});

Was ich nicht getestet habe, sind CSS-Class- und ID-Selektoren im XML. Ich kann mir allerdings gut vorstellen, dass diese ebenfalls funktionieren. Falls man CSS-Classes und IDs im XML nutzen möchte ;-)

LightCore 1.5.1 auf NuGet verfügbar

Die von Peter Bucher aktualisierte LightCore Version 1.5.1 ist nun auch auf Nuget verfügbar.

Das Core Package mit LightCore, Configuration und dem CommonServiceLocator für .NET4.0,  .NET3.5, .NET-CF3.5 und Silverlight:
https://nuget.org/packages/LightCore/

Das Web Integration Package für .NET4.0 und .NET3.5 und der Abhängigkeit zum Core Package:
https://nuget.org/packages/LightCore.WebIntegration/

Sollte irgendwas mit dem Package nicht stimmen, etwas fehlen, etc. freue ich mich über eine Nachricht um ein eventuelles Problem schnell beheben zu können.

(Diesmal waren die Package tatsächlich in 15 Minuten erstellt *fg*)

LightCore 1.5 auf NuGet verfügbar

Am 25. Januar 2013 hat Peter Bucher das Release 1.5 von LightCore bekannt gegeben.

Die aktuellen Bibliotheken sind auf der Website verfügbar, genauso wie eine ausführliche Dokumentation und der Zugang zu den Sourcen.

Als ich den Beitrag (leider etwas spät) in seinem Blog entdeckte, war das Grund genug für mich, dass ich mich gestern eine viertel Stunde hinsetze um die Nuget Packages auf NuGet.org aktualisieren.

Auf Anhieb wollte das nicht klappen, da sich NuGet seit ich die ersten LightCore Packages gemacht habe weiterentwickelt hat. Damals gab es noch keinen Owner, der einen als Herausgeber / Verwalter / etc. eines Packages kennzeichnet. Die alten Packages hatten also keinen Owner und ich war somit nicht berechtigt ein Update zu machen.

Ein Ticket bei der NuGet Gallery ein paar DMs per Twitter mit dem NuGet Gallery Team und der Owner war nachgetragen. Vielen Dank an dieser Stelle für die schnelle und unkomplizierte Hilfe durch das NuGet Team.

Aus der Viertel Stunde wurden dann halt doch insgesamt zwei, aber ich kann nun hiermit ankündigen, dass LightCore 1.5 auf und per NuGet verfügbar ist.

Das Core Package mit LightCore, Configuration und dem CommonServiceLocator für .NET4.0,  .NET3.5, .NET-CF3.5 und Silverlight:
https://nuget.org/packages/LightCore/

Das Web Integration Package für .NET4.0 und .NET3.5 und der Abhängigkeit zum Core Package:
https://nuget.org/packages/LightCore.WebIntegration/

Sollte irgendwas mit dem Package nicht stimmen, etwas fehlen, etc. freue ich mich über eine Nachricht um ein eventuelles Problem schnell beheben zu können.

Dependency Injection, ASP.NET MVC 4 und Autofac

In annähernd jedem Projekt nutze ich seit 2008 Dependency Injection (DI) um Komponenten und Module lose zu koppeln, die Nutzung zu Vereinfachen und vor allem, um die Testbarkeit zu gewährleisten.

DI gibt die Abhängigkeiten (Sub-Komponenten) von außen in die Komponente herein, statt innen zu erzeugen. Üblicherweise werden die Abhängigkeiten über den Constructor injiziert, in manchen Szenarien macht auch die Injektion über öffentliche Eigenschaften Sinn.

Beispiel abhängige Komponenten:

public class DataRepo
{
    public void SaveMyData(IEntity data) {}
}

public class BusinessService
{
    private readonly DataRepo _repo;
    public BusinessService()
    {
        _ repo = new DataRepo();
    }
}

In diesem Szenario kann die Komponente BusinessService nicht isoliert ohne das DataRepository getestet werden. Möglicherweise hat das DataRepository weitere Abhängigkeiten an eine Datenbank, was die Sache dann noch schwieriger macht.

Die Lösung bietet die Entkopplung der Komponenten:

public interface IDataRepo
{
    void SaveMyData(IEntity data);
}

public class DataRepo : IDataRepo
{
    public void SaveMyData(IEntity data) {}
}

public class BusinessService
{
    private readonly DataRepo _repo;
    public BusinessService(IDataRepo repo)
    {
        _ repo = repo;
    }
}

Nun kann ich die Instanz des DataRepository von außen hineingeben:

var repo = new DataRepository();
var service = new BusinessService(repo);

Im Falle eines UnitTest, kann ich eine Simulation eines Repository hineingeben, das Testdaten liefert oder so tut als würde es Daten speichern können.

IoC-Container

IoC-Container sind Werkzeuge, die einem das instanziieren der Objekte abnehmen, deren Lebenszeit verwalten können und in der Regel das hineingeben (injizieren) von Abhängigkeiten abnehmen. Alle IoC-Container machen das fast auf die gleiche Weise, mal mit etwas mehr, mal mit etwas weniger zusätzlicher Unterstützung.

Im Grunde wird einem IoC-Container immer nur mitgeteilt, für welches Interface er welche konkrete Klasse instanziieren und hineingeben kann. Dabei werden für die zu instanziierenden Klassen wieder die Abhängigkeiten aufgelöst und hineingegeben.

Mehr zu IoC-Container hat Peter Bucher in folgenden Beiträgen geschrieben:

Autofac

Autofac ist ein Leichtgewichtiger IoC-Container der unter anderem diverse Unterstützung für ASP.NET (Webforms, MVC3, MVC4 und Web API), MVC, MEF und SignalR bietet. Das Framework wird als Open Source auf Google Code gehostet. Autofac und die einzelnen Unterstützenden Bibliotheken können auch per NuGet in die Projekte integriert werden:
http://nuget.org/packages?q=Autofac

DI mit MVC

Hier möchte ich kurz vorstellen wie Autofac als DIIoCContainer in ASP.NET MVC4 genutzt werden kann, um Abhängigkeiten in Controllern und sogar in AktionFiltern aufzulösen.

Als ersten Schritt wird analog zu den anderen MVC Konfigurationen eine Klasse IocConfig im Verzeichnis App_Start angelegt. die dann ebenso in der Global.asax.cs aufgerufen wird.

public static void RegisterDependencies()
{
    var currentAssembly = typeof(MvcApplication).Assembly;

    var builder = new ContainerBuilder();

    builder.RegisterControllers(currentAssembly);
    builder.RegisterModelBinders(currentAssembly);
    builder.RegisterModelBinderProvider();
    builder.RegisterFilterProvider();
    builder.RegisterModule(new AutofacWebTypesModule());

    builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepository<>));
    builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork));

    var container = builder.Build();

    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}

Nach der Instanziierung des ContainerBuilder sehen wir hier die MVC4 Integration von Autofac:

  • RegisterControllers holt automatisch alle Controller aus der angegebenen Assembly und registriert sie im ContainerBuilder
  • RegisterModelBinders macht das wie RegisterControllers nur für ModelBinder
  • RegisterModelBinderProvider registriert den AutofacModelBinderProvider, eine Autofac Implementation des IModelBinderProvider
  • RegisterFilterProvider ermöglicht das injizieren von Abhängigkeiten in eigene ActionFilter
  • Als letztes in diesem Block sehen wir die Registrierung eines Moduls, welches die MVC spezifischen HTTP-Abstraktionen im ContainerBilder registriert, um diese automatisch in die Komponenten hineinzugeben.

In den nächsten zwei Zeilen sehen wir die Typische Registrierung von Mappings zwischen Interface und konkreten Klassen. In der ersten Zeile die Registrierung von generischen Typen die in meinem Fall sehr nützlich ist um mit einer Registrierung sechs bis sieben Daten-Repositories zu erschlagen.

Zuletzt wird der Container gebaut und dem AutofacDependencyResolver hinzugefügt, der wiederum als DepencyResolver dem ASP.NET MVC4 hinzugefügt wird.

Wer’s nicht glaubt, kann es gerne selber asuprobieren, aber das wars tatsächlich schon fast ;-)

Nun kann der MVC Controller einfach mit einem oder mehreren Constructor Parametern ausgestattet werden und wir können mit den injizierten Instanzen arbeiten als hätten wir sie selber erstellt:

public class HomeController : Controller
{
    private readonly IUnitOfWork _unitOfWork;
    public HomeController(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
[...]
}

Weitere IoC-Container

In den nächsten Beiträgen zeige ich die Konfiguration von folgenden weiteren IoC-Containern anhand des selben Szenarios

  • LightCore
  • Unity
  • NInject
  • StructureMap
  • Castle Windsor

[Update]

Auf Anfrage eines Lesers nehme ich noch StructureMap in die Liste mit auf und erweitere dann auch gerne um Castle Windsor. Ich muss allerdings dazu sagen, dass ich selber StructureMap und Castle Windsor nie selber verwendet habe und ich mich erst etwas einlesen muss.

Der genannte Leser würde hier im Blog auch gerne einen Vergleich der Container sehen. Wer noch? Eventuell lasse ich mich ja noch überreden. ;-)

[Update2]

“DI-Container” nach “IoC-Container” geändert. Danke an Laurent Bugnion der mich gestern in seinem Vortrag bei der Zurich Developers .NET User Group daran erinnert hat dass es da einen erheblichen Unterschied in der Definition gibt ;-)

LESS is more

Der Titel ist inzwischen auch schon abgegriffen, aber dennoch passend…

Um was geht es? Um die Vereinfachung von CSS in Webprojekten. Besonders um CSS einfacher zu erstellen und einfacher zu warten.

Mehr zu LESS gibt es hier zu lesen: http://lesscss.org/

Kurz zusammengefasst: LESS ist eine Sprache, mit der CSS um Variablen, Berechnungen, Art von Methoden (sog. “Mixins”), Operationen und Regeln erweitert wird. Dadurch wird CSS ein stückweit dynamischer.

Farben, Bilder, etc. lassen sich so z. B: in Variablen an zentraler Stelle anlegen und verwalten. Mixins sind ganze Blöcke von CSS Angaben die sich wiederverwenden lassen und Parameter zur Berechnung der CSS Werte zulassen. Werte (wie Breitenangaben) lassen sich berechnen.

Auch schön sind die Funktionen um mit Farben zu rechnen, so lassen sich Farben nun multiplizieren, addieren, verdunkeln, erhellen, etc. So ist es möglich, mit einer einzigen Farbangabe ganze Farbpaletten zu gestalten die immer zusammenpassen.

Üblicherweise wird LESS per Javascript in interpretierbares CSS “kompiliert”. Dazu wird die less.js (http://lesscss.org/images/download-button.png) im HTML eingebunden, welche LESS interpretieren und übersetzen kann. LESS kann so plattformübergreifend in allen Webprojekten genutzt werden.

Nun, die .NET-Community wäre nicht die .NET-Community, wenn es nicht irgendjemanden geben würde, der den LESS-Parser in .NET nachbaut. Und tatsächlich gibt es mit dotless (http://dotlesscss.org) eine Bibliothek, die es ermöglicht LESS Serverseitig zu interpretieren und als ehtes CSS an den Client zu senden. Dazu wird einfach ein HTTP-Handler in der Web.config registriert, der alle Dateien mit der Endung .less direkt verarbeitet:

<add type=" dotless.Core.LessCssHttpHandler ,dotless.Core" validate="false" path="*.LESS" verb="*" />

LESS und MVC4

Da ich nun sein einiger Zeit mit ASP.NET MVC4 arbeite, möchte ich natürlich LESS auch dort auf die MVC-Art nutzen. Klar, der HTTP-Handler würde auch mit MVC funktionieren, allerdings gibt es ein interessantes NuGet Package, dass LESS direkt in die MVC CSS Bundles integriert: https://nuget.org/packages/BundleTransformer.Less/

Ein weiteres Hilfsmittel ist ein Must-Have für alle Webentwickler die mit Visual Studio arbeiten. Ds sind die Web Essentials 2012 die als Erweiterung für Visual Studio installiert werden. Die Web Essentials bringen einen LESS Editor für das Visual Studio mit, das Syntax Highlighting, IntelliSense, eine Vorschau und einiges mehr mitbringt.

Nach der Installation des NuGet Packages, können die LESS Dateien in der MVC4 BundleConfig wie folgt eingebunden werden:


var css = new Bundle("~/bundles/css")
    .Include("~/Content/site.less", "~/Content/menu.less");
css.Transforms.Add(new CssTransformer());
css.Transforms.Add(new CssMinify());
css.Orderer = new NullOrderer();
bundles.Add(css);

Der CssTranformer sorgt hier für die Übersetzung des LESS in CSS. Der Minifyer ist der aus System.Web.Optimiation, der dafür sorgt, dass das CSS komprimiert (von unnötigen Whitespaces und Kommentaren befreit) wird. Der NullOrderer sorgt lediglich dafür, dass die Files in der angegebenen Reihenfolge verarbeitet werden, bzw. überschreibt den DefaultOrderer der die Files alphabetisch sortieren würde.

Nachdem das Bundle erstellt ist, kann es wie gehabt als CSS Bundle in der View eingebunden werden:

@Styles.Render("~/css/site")

So sieht der LESS Editor aus den Web Essentials 2012 im Visual Studio aus:

Anfänglich hatte ich mich gegen diese Einmischung in mein CSS etwas gewehrt, aber inzwischen weiß ich die eindeutigen Vorteile von LESS zu schätzen. Mehr zu LESS und den seinen Möglichkeiten sind hier zu finden: http://lesscss.org/#docs

Community, Windows 8 und Katzenhirn

Dank Lars Keller, habe ich dieses Wochenende am Community Open Day 2012 in München und Unterschleißheim teilnehmen können. Lars wies in einem INETA-Newsletter darauf hin, dass auch Community Leads teilnehmen können die nicht im CLIP-Programm sind.

Mit der Teilnahme erhoffte ich mir, eventuell doch noch für den .NET-Stammtisch Konstanz-Kreuzlingen in das CLIP-Programm aufgenommen zu werden und so etwas mehr Unterstützung für die Usergroup zu erhalten.

Das Event fand am ersten Tag in einer wirklich coolen Location in München mit diversen Vorträgen statt. Den zweiten Tag verbrachten wir dann in der Microsoft-Zentrale in Unterschleißheim. Die Veranstaltung war natürlich hauptsächlich geprägt durch Windows 8 und Windows Phone 8 aber auch einige andere Neuerungen wurden vorgestellt.

Mir war es allerdings wichtiger einige Leute aus der Developer Community zu treffen und mich mit denen zum Thema Community und Unterstützung durch Microsoft auszutauschen oder einfach mal so zu tratschen…

So wie es aussieht haben wir (der .NET Stammtisch Konstanz Kreuzlingen) mit Florian Endres jetzt einen Ansprechpartner der besser erreichbar ist als die Vorgänger und von dem wir uns die eine oder andere Unterstützung erhoffen können. Was das CLIP-Programm angeht, schauen wir einfach mal was sich ergibt. Die Aussichten sind auf jeden Fall nicht schlecht.

Was hat das nun mit Katzenhirn zu tun?

Katzenhirn ist recht klein und man übersieht es schnell wenn man zügig auf der Autobahn von Lindau nach München fährt. Erst auf der Rückfahrt ist es mir aufgefallen und ich musste drei… nein… viermal schauen um sicher zu gehen, dass ich mich nicht geirrt habe. Katzenhirn.

See# Conference 2012 wird leider abgesagt

Leider laufen viele Dinge anders als vorher geplant. Deshalb müssen wir die See# Conference 2012 leider absagen. Es sind viele Gründe, die zu dieser Entscheidung geführt haben. Die wichtigsten Gründe:

  • Zwei von uns können dieses Jahr leider doch nicht die nötige Zeit aufbringen um die Organisation der Veranstaltung zu unterstützen. Für den Rest des Teams wäre das eine ziemliche Anstrengung die Konferenz dennoch durchzuführen.
  • Seit dem Aufruf zum Call-for-Papers haben wir sage und schreibe vier Vortragsvorschläge bekommen. Trotz dem Interesse im Vorfeld.
  • Auch von Seiten der Sponsoren sieht es dieses Jahr nicht allzu gut aus. Auch wenn ich dieses Jahr mit meiner eigenen Firma als zahlender Sponsor dabei gewesen wäre.

Ob es eine eventuelle See# Conference 2013 geben wird, ist noch offen. Keiner aus dem Team möchte die Idee komplett aufgeben. Eventuell wird es aber auch mehrere kleinere Events im Jahr geben, die Logistisch keine so große Herausforderungen sein werden. Ideen dafür gibt es genug:

  • Regelmäßige Coding-Dojos nach dem Vorbild in Karlsruhe
  • Robocode-Battles zwischen Java- und .NET-Entwicklern in der Region
  • Open Space Veranstaltungen

Da das Organisations-Team der See# Conference fast identisch mit dem Vorstand des .NET-Stammtisch Konstanz-Kreuzlingen ist, werden wir zu dem Thema auf jeden Fall im Gespräch bleiben. Ich bin auf jeden Fall gespannt was am Ende dabei herauskommt.

Themenwahl und CfP für die See# Conference 2012 gestartet

Letzte Wochen haben wir die .NET-Community aufgefordert Themenwünsche für die See# Conference 2012 einzureichen. Dafür habe ich eine Umfrage auf tricider.com gestartet:

https://tricider.com/de/brainstorming/G5ci

Hier könnt ihr eure Idee und Argumente veröffentlichen und für vorgeschlagene Themen abstimmen. Diese Umfrage läuft noch ein paar Woche. Ich fordere euch also hiermit auf weitere Ideen einzutragen :-)

Call for Papers

Falls Ihr Interesse habt an der See# Conference 2012 in Kreuzlingen einen Vortrag zu einem .NET-Spezifischen Thema zu halten, seid Ihr herzlich eingeladen uns Eure Vorschläge einzureichen.

Dazu benötigen wir folgende Daten von Euch:

  • Titel des Vortrags
  • Abstract/Kurzbeschreibung
  • Kurzbiographie und Foto
  • E-Mail Adresse (optional Handynummer für Notfälle)
  • optional: Website / Blog / Twitter / XING Profil

Alle Vorträge dauern 60 Minuten.

Die Anmeldung sollte per E-Mail mit dem Betreff "See# Conference: Vortragsvorschlag" an info@dotnetkk.de gesendet werden.

Euer Ansprechpartner für die Themen und die Agenda werde ich dieses Jahr selber sein. Ich werde dieses Jahr die Vortragsvorschläge anhand der Themenvorschläge aus der .NET-Community auswählen.

Weitere Informationen findet Ihr unter: http://www.seesharp-conference.net/de/Agenda/Call-for-papers/page38399.htm

See# Conference 2012

Vor einigen Wochen habe ich per Doodle eine kleine Stimmungsumfrage gestartet, um zu sehe, wie das Interesse an einer weiteren Veranstaltung des .NET-Stammtisch Konstanz-Kreuzlingen aussieht.

Kurz nach dem ersten Ansturm auf die Umfrage ist das neue Team dann zusammengesessen und hat überlegt, ob und wie die neue Veranstaltung denn konkret aussehen soll. Uns war wohl allen klar, dass wir die Veranstaltung auf jeden Fall noch einmal versuchen wollen, sofern die Umfrage positiv verläuft. Und so wie es hier aussieht nenne ich das sehr positiv:

Ich möchte mich bei allen Teilnehmern der Umfrage hiermit ganz herzlich bedanken. Dieses Ergebnis hat unsere Motivation für eine weitere Veranstaltung noch mehr verstärkt.

Das Team

Im Team gab es ein paar Veränderungen. So wird uns Golo Roden – der letztes Jahr eine großartige Agenda mit vielen tollen Sprechern aufgestellt hat - leider nicht mehr aktiv im Team unterstützen. Auch Markus Schmid möchte sich dieses Jahr nicht mehr an der Organisation der Veranstaltung beteiligen.

Wenn auch nur im Beck-End, so bekommen wir doch starke Unterstützung von Patrick Kress, der die organisatorischen Fäden (Zügel?) zusammenhalten wird.

Weiterhin mit dabei sind Stefan Zybarth (Combit GmbH) für PR und Helfer, Tilo Schinke (Ontrex AG) für Finanzen, Catering und Location und zu guter Letzt meine Wenigkeit als Ansprechpartner für Sponsoren, Sprecher und Teilnehmer.

Für die Auswahl der Themen möchten wir dieses mal die .NET-Community beauftragen ;-)
Parallel zum CfP starten wir eine Umfrage zur Themenwahl. Sprecher und Vorträge werden wir dann anhand der gewählten Themen aus den Eingängen des CfP auswählen.

Neuer Name

Die Änderung des Namens hatte mehrere Gründe: Zum einen gab es nie eine Party (außer die traditionelle Kennenlern-Party am Vortag) und zum anderen gab es auf der Seiten der Teilnehmer Schwierigkeiten vom Arbeitgeber eine Party am Samstag gezahlt zu bekommen.

Zum anderen wollen wir uns auf das Konferenz-Schema festlegen, da es in dieser Region keine Konferenz dieser Art gibt. Auch wenn es in der .NET-Community den Anschein hat, dass es inzwischen reichlich Veranstaltungen der .NET-Community gibt, so sind es doch viele verschiedene Arten und keine welche den Bodenseeraum und alle vier anliegenden Länder ansprechen soll.

Die Website wird in Kürze unter der Adresse seesharp-conference.net erreichbar sein. Unser Sponsor und Hosting Provider die K&K Internet GmbH wird die nötigen Einstellungen im IIS noch machen müssen und wir werden noch ein paar Änderungen auf der Website machen müssen.

Als Twitter-Hashtag wird wohl #SSC12 herhalten.

Location und Termin

Die See# Conference wird, wie die Veranstaltungen zuvor wieder im DREISPITZ Sport- und Kulturzentrum in Kreuzlingen statt finden. Hier sind wir gut betreut, fühlen uns wohl, der Caterer hat eine Küche vor Ort. Weiterhin bekommen wir als Kreuzlinger Verein die Location zum halben Preis und die Stadt Kreuzlingen freut sich, dass sie auch eine IT-Veranstaltung im Angebot hat :-)

Was den Termin angeht, so können wir unser Versprechen, einen Termin außerhalb der Sommerferien zu finden, leider nur für die Schweiz einlösen. Der Termin für die See# Conference 2012 wird

Freitag der 31. August 2012

sein. Das war der einzige Termin der im Spätsommer, bzw. Herbst noch frei war. Das nächste mal werden wir wohl schon 14 Monate im Voraus buchen müssen. Allerdings spricht das ja auch für das DREISPITZ. Vielen Dank - an dieser Stelle - an die Stadt Kreuzlingen für die Unterstützung bei der Terminfindung. (Ich freu mich schon jetzt wieder auf die interessanten Gespräche mit dem Hauswart Herrn Keller *fg*)

Verpflegung

Erst der Negative Punkt: Bei der letzten Veranstaltung mussten wir sehr viele Flaschen selber einsammeln und in die bereitgestellten Behälter entsorgen, aber das alleine ist nicht das Problem, sondern die Tatsache, dass die ca. Hälfte dieser Flaschen nicht ganz lehr waren, bzw. teilweise noch mehr als halb voll waren. Da der Inhalt der Flaschen einen gewissen Wert besitzt der auf die Teilnehmer umgeschlagen werden muss und da es einfach nur schade darum ist Lebensmittel entsorgen zu müssen, wollen wir das aus Ökologischen und Ökonomischen gründen von vornherein begrenzen. Wir werden deshalb, wie bei der ersten Veranstaltung, nur drei Getränke kostenfrei bereitstellen. Alle weiteren Getränke werden zum Selbstkostenpreis abgegeben. Außerdem werden wir ein Flaschenpfand einführen.

Die positiven Punkte: Der negative Punkt gilt nur für Softdrinks in Flaschen. Kaffee und Tee gibt es natürlich weiterhin kostenfrei. :-) Als Caterer werden wir schauen dass wir wieder das Hotel ZIIL bekomme können. Im Gegensatz zum Caterer der ersten See# Party, lief die Abwicklung mit dem Hotel ZIIL absolut stressfrei und lecker war es auch.

Also…

…alle die in der Umfrage für die Veranstaltung gestimmt haben möchte ich auch auf der See# Conference sehen ;-)

Ich freue mich drauf ein drittes mal eine solche Veranstaltung machen zu können und lade alle herzlich dazu ein, als Teilnehmer, als Sponsor oder als Sprecher, das Event einen noch größeren Erfolg werden zu lassen als die vergangenen Veranstaltungen :-)

Silverlight und Spekulationen rund um das Thema

Eigentlich habe ich das Thema inzwischen satt, ich beobachte es schon seit knapp einem Jahr und nirgends sind klare Aussage zu finden, sondern nur wilde Spekulationen. Das ging im letzten halben Jahr nicht nur so weit, dass Silverlight in Frage gestellt worden ist, sondern auch das .NET Framework.

Klar ist, dass von Microsoft keine klaren Informationen zu dem Thema kommen. Klar ist dass es dadurch etwas Verunsicherung beim Thema Silverlight gibt.

Ich teile die Meinung, dass Silverlight-Projekte im Moment eine schlechte Idee seien, absolut nicht. Vielleicht bin ich aber auch nicht paranoid genug… ;-)

Wie auch immer… komme ich im Moment entwickelnd und beratend mit einigen neuen Silverlight-Projekten in Berührung. Es stehen auch einige Anfragen an… Aus meiner Sicht gibt es im Moment keinen Grund zu behaupten, dass Silverlight tot ist. Andererseits gibt es auch keine Informationen ob es ein Silverlight 6 geben wird oder nicht. Im Gegenteil konzentriert sich Microsoft auf HTML5

Aber ist das schlimm? Könnte das ein Problem für Silverlight sein?

Aus meiner Sicht nicht. Denn in einem einzigen Punkt stimme ich mit Steve Jobs (RiP) überein. Silverlight und Flash haben im Web nichts zu suchen und hatten es auch nie. Flash hatte sich fälschlicherweise fast als ein Standard im Web durchgesetzt. Kein Wunder, war es bis zu Silverlight doch auch die einzige Möglichkeit schnell schöne Rich Internet Applications zu schreiben. Ich habe selber habe (nicht nur fürs Web) Anwendungen mit Flash erstellt.

Silverlight ist eine Alternative zu Flash, die sich zwar als Technologie, aber im Web kaum durchgesetzt hat. (Allerdings: Erst vor ein paar Monaten hat Amazon den Videoplayer für die Filme auf lovefilm.de von Flash auf Silverlight ändern lassen.) Das hat sicher auch einigen klar gemacht, dass beide Technologien ihre Daseinsberechtigungen haben, aber nicht im Web, sprich nicht für alle Benutzer und nicht für alle Endgeräte. Wieso auch…

Dafür gibt es bereits einen Standard und der heißt HTML. ;-)

Jetzt mit HTML5 haben auch die Videoplayer mit Flash oder Silverlight keine Daseinsberechtigung mehr. Und das ist auch gut so, so ist es möglich eine Website mit allen Inhalten, für alle Benutzer und allen Endgeräten zur Verfügung zu stellen. Genial oder? Ich finde es jedenfalls genial…

Und wo hat Flash und Silverlight noch eine Daseinsberechtigung?

Überall dort wo HTML aufhört,  bzw. überall dort wo HTML zu aufwendig wäre und überall dort wo die Zielgruppe eingeschränkt ist. In den aktuellen Projekten, an denen ich beteiligt bin, ist die Zielgruppe begrenzt, bzw. den Benutzern kann also die Systemvoraussetzungen genannt werden. Bei allen Projekten handelt es sich um Geschäftsanwendungen.

Und Silverlight 6? Benötigen wir ein Silverlight 6?

Wenn die Tatsache stimmt, dass die XAML-Schicht mit Silverlight 5 und WPF 4.5 identisch sein kann, so wird Silverlight 6 nicht mehr benötigt. Wieso auch? Wir haben dann eine Technologie mit der Bezeichnung XAML mit C#, bzw. XAML mit VB. Basierend auf unterschiedlichen Frameworks. Ehrlich gesagt, finde ich diese Vorstellung gar nicht mal so übel…

Einzig eine Frage die ungeklärt ist, ist das Silverlight-Plug-In… Aber Moment mal… Hat sich Microsoft, nicht selber verpflichtet jedes Produkt mindesten zehn Jahre zu supporten?

Nebenher: Wer glaubt eigentlich wirklich, dass eine Software zehn Jahre lang aktuell bleibt?

Wir können also noch ein paar Jahre XAML mit C# oder VB im Silverlight Plug-In laufen lassen… Und dann ist .NET fast zwanzig Jahre alt… Und dann? Möglicherweise wird das Plug-In dann nicht mehr Silverlight heißen… Möglicherweise auch ganz was anderes…

Ich möchte hier nicht auch noch anfangen zu spekulieren, sondern nur sagen, dass ich mir erst mal keine Sorgen um die Technologie Silverlight mache. Das heißt nicht, dass man nicht dennoch über den Tellerrand schauen sollte um anderes und neues zu lernen. Ganz im Gegenteil… ;-)

Continous Delivery per Dropbox

Neulich hatten wir das Problem, dass wir sehr schnell eine ASP.NET MVC Anwendung auf einen Testserver bringen mussten. Die Lösung lag direkt vor der Nase:

  • Wir richteten auf dem Buildserver und den Testserver Dropbox ein.
  • Der Buildserver (in unserem Fall ist es Jenkins) baut (bei jeder Änderung im Source Code Management) die Anwendung und kopiert den Output das entsprechende Dropbox-Verzeichnis.
  • Dropbox synchronisiert nun die Files mit dem Testserver
  • Auf dem Testserver zeigt das Web im IIS direkt auf das entsprechende Dropbox-Verzeichnis und die Web-Anwendung kann direkt aufgerufen und getestet werden.

Nachteile:

  • Der User unter dem der Dropbox-Dienst läuft muss auf den Servern angemeldet bleiben.
  • Es kann zu Synchronisationkonflikten kommen, wen auf dem Testserver ebenfalls Files verändert werden.

Heinweis:

Continous Delivery über die DropBox sollte auf keinen Fall produktiv genutzt werden und ist allerhöchstens für die private Umgebung sinnvoll. Zum einen sind die oben genannten Nachteile recht störend, wenn man viel Änderungen macht, zum anderen ist Dropbox zwar ein hilfreiches Tool, aber nicht wirklich 100% vertrauenswürdig.

Ein Blick auf das Entity Framework 4

Angeregt durch ein aktuelles Projekt, musste ich mir das Entity Framework 4 (Microsofts OR-Mapper) anschauen. Bisher hatte ich es vermieden, da ich der Meinung war, dass ich die nötigen Mappings nur über den Designer mit viel Magie und wildem herumgeklicke herstellen kann. Allerdings halte ich es für wichtig, dass die Entities, die ich in meinen Projekten benötige, nicht autogeneriert sind, bzw. nicht vom OR-Mapper generiert werden, da dadurch unnötige Abhängigkeiten zum OR-Mapper entstehen oder unnötige Objekt-Mappings gemacht werden müssen.

Üblicherweise halte ich meine Entities in einem Projekt, das von allen anderen Projekten referenziert wird, die mit diesen Entities arbeiten. Mit NHibernate ist das auch problemlos möglich.

BTW: Ich bin ein großer Fan von NHibernate und nutze diesen OR-Mapper bisher in fast jedem großen Projekt.

Ich möchte also meine Entities wie folgt aufbauen:

public class Customer : EntityBase
{
    [StringLength(150)]
    [Required]
    public string Name { get; set; }
    [StringLength(100)]
    [Required]
    public string Street { get; set; }
   
    [StringLength(5)]
    [Required]
    [RegularExpression("^[0-9]{4,5}$")]
    public string Postalcode { get; set; }
}

EntityBase ist eine Basisklasse, welche die Id bereitstellt, Equals überschreibt, etc. Die hier sichtbaren Attribute stammen von den DataAnnotations und werden zur Validierung genutzt.

Würde ich jetzt das EF wie gewohnt einsetzen, müsste ich z. B. per AutoMapper von den generierten Entities auf meine Mappen. Das möchte ich nicht, bzw. müsste es mit NHibernate auch nicht tun.

DbContext

Nun war es heute René Leupold der mir mit seinem Blog http://databinding.net den entscheidenden Tipp für den DbContext gab. Mit dem DbContext ist es möglich das Entity Framework ähnlich wie NHibernate zu verwenden.

Hilfreich ist auch die Artikelserie “Using DbContext in EF 4.1” im ADO.NET Team Blog

Der DbContext ist ab EF 4.1 verfügbar. Ich selber habe mir für diese Beispiele die EntityFramework.dll 4.2.0.0 per NuGet referenziert.

Das Mapping

Was wir zusätzlich benötigen ist ein Mapping, das hier per Fluent API per C# gesetzt wird:

internal class CustomerMapping : EntityTypeConfiguration<Customer>
{
    public CustomerMapping()
    {
        Property(x => x.Name)
            .HasMaxLength(200)
            .IsVariableLength()
            .IsUnicode()
            .IsOptional();
        Property(x => x.Postalcode)
            .HasMaxLength(30)
            .IsVariableLength()
            .IsUnicode()
            .IsOptional();
    }
}

Genutzt wird die Konfiguration dann im DbContext:

public class DataContext : DbContext
{
    public IDbSet<Customer> Customers { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Configurations.Add(new CustomerConfig());
    }
}

Die Ähnlichkeit mit NHibernate ist an dieser Stelle eindeutig und ich habe meine gewünschte Trennung zwischen den Entities und dem OR-Mapper.

Die Connection

Interessant ist, dass die Verbindung zur Datenbank über den Constructor der Basisklasse DbContext gesetzt werden kann oder aber per Konvention:

<connectionStrings>
    <add name="DataContext"
         providerName="System.Data.SqlClient"
         connectionString="Data Source=[…]" />    
</connectionStrings>

Der Name des ConnectionStrings muss einfach so heißen wie der entsprechende DbContext

Benutzen

Wenn die DB schon existiert ist das im Prinzip auch schon alles um mit den Daten zu arbeiten:

[Test]
public void SetAndLoadCustomerFromDataBase()
{
    IEnumerable<Customer> customers;
    using (var context = new DataContext())
    {
        context.Customers.Add(new Customer
                                  {
                                      Id = Guid.NewGuid(),
                                      Name = "Hallo Welt",
                                      Street = "Hallo Street 2",
                                      Postalcode = "12345"
                                  });
        context.SaveChanges();
    }
    using (var context = new DataContext())
    {
        customers = context.Customers.Select(c => c).ToList();
    }
    Assert.That(customers.Count(), Is.GreaterThan(0));
}

Das Mapping wird erzeugt, wenn das erste mal der DataContext instanziert wird. Es wird relativ viel mit Lazy<T> gearbeitet, so dass das Debugging der ergebnislisten nicht immer ganz einfach ist.

 

Demo

Eine Demo werde ich in den nächsten Tagen hier anhängen. Die vorhandenen Projekte muss ich erst noch anonymisieren.

Fazit

Mit dem DbContext scheint das EntityFramework doch noch ein ganz passables Werkzeug und eine ernstzunehmende Alternative zum NHibernate zu sein.

Mal wieder was neues…

Der letzte Post in diesem Blog ist nun leider schon wieder eine Weile her. Seit dem letzten Eintrag ist aber auch einiges passiert:

Viele haben es sich er mitbekommen, dass ich ab Oktober mein eigenes Unternehmen gestartet habe. So eine Gründung ist ja nicht einfach mal schnell von heute auf morgen erledigt, sondern nimmt einen schon ganz schön in Anspruch.

Mit der GUTSCH-ONLINE Software GmbH möchte ich genau das anwenden, was ich in den letzten 10 Jahren gelernt habe um Software entwickelnde Unternehmen bei Ihrer Arbeit zu unterstützen. Entwicklung, Beratung und Schulungen sind die Kernthemen der Firma.

Die ganze Gründung passierte außerdem parallel zur Vorbereitung auf die See# Party 2011, die am 20. August stattfand. Übrigens war die auch wieder ein ein voller Erfolg. Dank weitsichtigerer Planung sind wir diesmal auch nicht auf den Kosten sitzen geblieben.

Auch der .NET-Stammtisch Konstanz-Kreuzlingen musste unter den Vorbereitungen der Firmengründung und der See# Party 2011 leiden. So wurden die letzten Stammtisch-Termine immer erst kurz vor den Treffen bekanntgegeben und einige Mitglieder waren etwas verunsichert über kommende Termine.

Da nun aber die See# Party 2011 rum ist und die eigene Firma so langsam in Fahrt kommt, gelobe ich Besserung und plane am Wochenende die nächsten sechs Sessions der .NET-Stammtisches, die übrigens die nächsten Male immer im Quellenhof in Kreuzlingen stattfinden werden, da die Location in Konstanz etwas unzuverlässig wurde und lieber lukrativere Events auf unsere Reservierung gebucht hat.

Wie auch immer…

… in Zukunft wird es wieder etwas mehr von mir zu lesen geben. Versprochen. :-)

Als nächste wird es einen kleinen Beitrag über eine ganz simple Möglichkeit von Continous Delivery geben.

Mehr Beiträge Nächste Seite »