Archiv für den Monat Oktober 2011

Zwischenfazit Social Media – Teil 1

Das Gelände abstecken

Im Dezember 2010 ging ich auf die Geschäftsleitung zu, um mit ihr über das Thema Social Media zu sprechen. Ich erklärte ihnen, dass ich darin interessante und vor allem auch neue Möglichkeiten sehen würde, um strategische Unternehmensziele zu unterstützen. Dazu wollte ich eine spezielle Arbeitsgruppe gründen, bei der wir es allen Mitarbeitern aus allen Abteilungen unter 26 freistellten daran teilzunehmen. Die IT sollte in diesem Rahmen die Planung und technische Unterstützung übernehmen. Die Freigabe dafür erfolgte sofort, sodass wir nach einer kurzen Vorbereitungszeit meinerseits im Februar 2011 unser erstes Treffen abhalten konnten.

Die Gruppe umfasste 17 Personen. Wir hatten Mitarbeiter aus den Abteilungen Lager, Fertigung, Einkauf, Buchhaltung, Verkauf, Marketing und sogar aus Niederlassungen mit an Bord. Die Altersschere ging vom Jüngsten mit 16, einem neuen Azubi, bis zum Ältesten mit 31, einem unserer IT-ler. Nahezu die Hälfte war in einer Ausbildung. Ein gutes Drittel waren Frauen. Die wenigsten hatten nennenswerte Erfahrungen mit Projektmanagement.

Bis zu diesem Zeitpunkt gab es von uns keinerlei Präsenz in den neuen Kanälen. Viele waren natürlich privat bereits auf Facebook unterwegs, wenige auf Xing und gänzlich niemand war auf Twitter vertreten. Einen Blog führte, wenn ich mich recht erinnere, ebenfalls niemand. Selbst von meinen IT Kollegen hatte bis dato keiner einen Twitter Account oder einen Blog.

 

In meinem nächsten Blogeintrag gehe ich auf die Überzeugungsarbeit ein, die man gegenüber der GL leisten muss.

Werbung

FakeItEasy and Castle.Core conflict

Hey guys, i want to point a FakeItEasy problem out to you. If you use the most current version of Castle.Windsor 3.0.* you will run into an assembly conflict with FakeItEasy as FIE has a dependency on Castle.Core 2.5.*. There is a simple workaround: Don’t use NuGet to install FIE instead download it manually. The download is an ILmerged assembly!

You can find more informations in the according issue.

Adding a new developer to your Git Repository

First of all, this is just a walkthrough for Windows!

 

1. Download and install Git. I prefer the installation without msysGit

image

2. Install Git. Make sure you have admin rights (for example if you’re using the UAC). Here are my recommended settings:

 

image

image

image

 

3. Setup your git config. You should set at least the following two configuration settings:

git config -–global user.name “your name”

git config -–global user.email “your email”

You have to enter this commands in the Git Bash! After finishing, there should be a “.gitconfig” file in your user directory.

image

Here are some recommendations of mine. Feel free to just copy and paste it:

[alias]
    review = log -1 –patch
    unstage = reset head
    aa = add –all
    au = add –update
    s = status
    p = pull
    l = log –oneline -10
    k = !gitk –all & –all &
    aua = !git add –update && git commit –amend –reuse-message=HEAD
    aaa = !git add –all && git commit –amend –reuse-message=HEAD
    amend = commit –amend –reuse-message=HEAD
    aucp = !sh -c ‚git add –update && git commit -m \"$1\" && git push‘ –
        aacp = !sh -c ‚git add –all && git commit -m \"$1\" && git push‘ –
[branch]
    autosetupmerge = true
    autosetuprebase = always
[color]
    ui = auto
    wtf = true
[color "diff"]
    old = bold red
    new = bold green
    meta = bold yellow
[color "branch"]
    current = black green
    local = bold green
    remote = yellow
    plain = bold yellow
[color "status"]
    added = bold red
    changed = bold green
    untracked = bold cyan
    nobranch = red reverse
[color "interactive"]
    prompt = bold green
    error = bold red

4. Generate the RSA Keys by entering the following command in the bash shell:

ssh-keygen –C “your name” –t rsa –v

Be careful: Don’t enter a filename as it won’t generate the needed .ssh directory in your user dir! Read more in this article.

image

If the operation was successful, you will find the private and public keys in your user directory in the invisible direcotry “.ssh”. It’s important that the filenames are “id_rsa” and “id_rsa.pub” because Git is using by convetion these files to access the server.

5. Copy the “known_hosts” file from a co-worker and put it into your .ssh directory.

6. Add your public key to the remote git server. In my case, i have a local copy of the gitolite-admin directory on the server.  So all i have to do is adding the new public key to the “keydir” directory and edit the “gitolite.conf” file in the “conf” directory:

 

image

7. Create a local copy of the development repository:

git clone git@ci:WebDevelopment.git

WebDevelpment.git is the name of the repository and ci is the server name. Make sure you are in the directory where you want to create the clone!

 

8. Some more references

http://help.github.com/win-set-up-git/

http://kylecordes.com/2008/git-windows-go

 

9. Think about using symbolic links for the “.ssh” dir and the “.gitconfig” file. You can use the mklink command from windows. I use this way to sync all my machines.

Entity Framework FAQs

Da ich mich in Zukunft noch mehr mit dem Thema beschäftigen und in Folge dessen auch vermehrt Content publishen will, sammle ich die am häufigsten gestellten Fragen. Hier ist mein bisheriger Stand.

  • Versionierung: Down- und Upgrades des DB Schemata und das Deployen beim Kunden
  • Stored Procedures: Viele berichten, sie hätten von Problemen diesbezüglich gehört. Was geht denn nun tatsächlich und was nicht
  • Validation
  • Rights Management
  • Performance: Worauf muss ich achten, was sind bekannte Schwächen
  • Unit Tests / Integration Tests: Hier geht es v.a. um die architektonische Implementierung, sowie das Erzeugen von Seed Daten
  • Architektur: Wie implementiere ich das Entity Framework sinnvoll in meine Anwendungsarchitektur
  • Code First: Was ist bereits möglich, wie kann ich eingreifen
  • Interceptors / Extensions: Typischerweise wollen die meisten hier wissen, wie man bei einer Änderung der Entität Logik auslösen kann. Oftmals sollen in dieser Logik die restlichen Entitäten des Models verändert werden
  • Anzeige der Daten / Binding

Falls ein Punkt noch nicht angesprochen wurde oder ihr spezifische Fragen habt, dann schickt mir diese bitte über die gängigen Kommunikationskanäle wie Emails, Tweets oder Facebooks Messages.

Open Space 2011 Nord

Für mich ging soeben der Open Space in Leipzig zu Ende. Ich habe mehrere positive Punkte mitgenommen:

  • An Infos zum Entity Framework besteht großes Interesse, sodass 2 Sessions von mir dazu sehr gut besucht waren und ich viele Anregungen für weitere Vorträge bzw. Artikel mitnehmen konnte
  • Viele der von mir besuchten Sessions brachten mir qualitativ guten Input, z.B. zu den Themen CQRS, Flow Design und Contract First
  • Ich konnte wieder neue Leute kennen lernen und neue Kontakte knüpfen, aber auch mal wieder alte Gesichter sehen
  • Ich habe einen Einblick bekommen, wo die Probleme in anderen Teams bzw. bei Projekten liegen (seltsamerweise sind hier viele Developer bei exakt den gleichen Punkten sehr unzufrieden, obwohl der Arbeitsmarkt momentan offensichtlich ein Arbeitnehmermarkt ist)
  • Der Zeitplan passte sehr gut, auch wenn wir am ersten Tag mit einer kleinen Verspätung angefangen haben. Am Ende des Tages war ich in einem angenehmen “ausgewogenen geistigen Zustand”, sprich ich war nicht total ausgebrannt
  • Mit dem Best Western Hotel waren wir ganz zufrieden. In jedem Fall lässt es sich dank guter Isolierung geräuscharm schlafen. Beim Frühstück gibt es auch nichts zu meckern
  • Ganz große Klasse war, dass die Organisatoren sich die Mühe gemacht und für jeden Visitenkarten vorbereitet hatten. Allerdings sollte hier nächstes Jahr noch der Blog drauf
  • Tablets sind definitiv auf dem Vormarsch. Gleiches gilt für Ebook Reader, auch wenn es enttäuschend ist, dass PDFs dafür weniger geeignet sind
  • Die Microsoft Evangelisten Tom und Felix haben sich für eine Microsoft Bash Session zur Verfügung gestellt. Top!
  • Das Essen war gut und reichlich
  • Mit den Service Damen war es sehr angenehm zu flirten ;)

Weniger positiv empfand ich:

  • Dass die Sessions zum großen Teil starke Consumer Sessions waren, weil viele Teilnehmer primär konsumieren wollten
  • Dass es nicht ganz so viele Sessions zur Auswahl gab, wie ich es mir gewünscht hätte, auch wenn es für mich in jeder Rune mind. eine gute Session gab
  • Das W-LAN war sporadisch nicht erreichbar/überlastet, aber das können auch Probleme meinerseits gewesen sein
  • Durch die Räumlichkeiten des Pubs gab es leider viele kleine, verteilte Gruppen. Ich persönlich finde ein großes Lokal bzw. einen großen Raum, wo die Mehrzahl der Teilnehmer zusammen untergebracht wird, besser. Aber das soll wohl nicht so einfach möglich sein
  • Vielleicht sollte man nächstes Jahr mehr Stromquellen zur Verfügung stellen
  • Parallelprogrammierung für PC Anwendungen ist immer noch kein sonderlich gefragtes Thema bei Entwicklern. Schade!
  • Die Beamerauflösung könnte doch etwas höher sein
  • Leider waren die Service Damen abends im Pub nicht dabei… @Torsten: Sicherlich der wichtigste Punkte, den es zu optimieren gilt

An dieser Stelle möchte ich mich ganz herzlich bei den Organisatoren und Sponsoren bedanken. Allen voran natürlich Torsten und Alex. Eure Namen sollen klingen!

Die wichtigste Nachricht zum Schluss: Auch nächstes Jahr wird es wieder einen Open Space in Leipzig geben. Der Termin steht bereits fest. Es ist der 20-21 Oktober 2012.

Fake Implementation of IDbSet

   1: public class FakeDbSet<T> : IDbSet<T> where T:class 

   2:  {

   3:      readonly HashSet<T> _set;

   4:      private readonly IQueryable<T> _queryableSet; 

   5:  

   6:      public FakeDbSet()

   7:      {

   8:          _set = new HashSet<T>();

   9:          _queryableSet = _set.AsQueryable();

  10:      } 

  11:  

  12:      public IEnumerator<T> GetEnumerator()

  13:      {

  14:          return _set.GetEnumerator();

  15:      }

  16:  

  17:      IEnumerator IEnumerable.GetEnumerator()

  18:      {

  19:          return GetEnumerator();

  20:      }

  21:  

  22:      public Expression Expression

  23:      {

  24:          get { return _queryableSet.Expression; }

  25:      }

  26:  

  27:      public Type ElementType

  28:      {

  29:          get { return _queryableSet.GetType(); }

  30:      }

  31:  

  32:      public IQueryProvider Provider

  33:      {

  34:          get { return _queryableSet.Provider; }

  35:      }

  36:  

  37:      public T Find(params object[] keyValues)

  38:      {

  39:          throw new NotImplementedException();

  40:      }

  41:  

  42:      public T Add(T entity)

  43:      {

  44:          _set.Add(entity);

  45:          return entity;

  46:      }

  47:  

  48:      public T Remove(T entity)

  49:      {

  50:          _set.Remove(entity);

  51:          return entity;

  52:      }

  53:  

  54:      public T Attach(T entity)

  55:      {

  56:          _set.Add(entity);

  57:          return entity;

  58:      }

  59:  

  60:      public T Create()

  61:      {

  62:          throw new NotImplementedException();

  63:      }

  64:  

  65:      public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T

  66:      {

  67:          throw new NotImplementedException();

  68:      }

  69:  

  70:      public ObservableCollection<T> Local

  71:      {

  72:          get { throw new NotImplementedException(); }

  73:      }

  74:  }

ReSharper Settings für Unit Tests

Wer Probleme bei seinen Unit Tests hat, weil für den Unit Tests die Assemblies in ein temporäres Verzeichnis kopiert und dort ausgeführt werden, der kann dies in den ReSharper Settings über die Settings “Shadow-copy assemblies being tested” deaktivieren.

Bei mir traten Probleme in einem Unit Test für meinen IoC-Container auf. Hintergrund ist der, dass im Test alle DLLs nach IWindsorInstaller Implementierungen durchsucht und registriert werden. Da nicht alle DLLs vorhanden waren, kam es zu Fehlern.

image

Smart overriding of the SaveChanges-Method of the EntityFramework

 

As part of our refactoring of the persistence layer implemented with the Entity Framework, we developed an approach for some tricky problems. Although i just discuss one specific scenario, the following solution is probably useful for many different issues:

We are using some objects which won’t be deleted in the classic way by removing them from the underlying database table. Instead, we mark them as deleted, set the purge date and the user who initiated the action. The same procedure exists for creating and modifing objects. You surely can imagine why we are doing this. So how can we achieve this behaviour in a transparent, implicit manner.

Step 1: Set up some interfaces like IHaveCreationDate, IHavePurgeDate and IHaveModificationDate.

   1: public interface IHavePurgeDate

   2: {

   3:     void SetPurgeDate();

   4: }

 

Step 2: Now it depends on your engineering strategy: Code First, Model First or Database First. According to your strategy you might using POCOs or you don’t. First of all, you can implement this solution in every single case, but you might change a little of the implementation. Here’s the way like we are using it with our POCOs (take a look at the ADO.NET Team Blog about the usage of POCOs) automatically generated by the EF:

Auto generated code:

   1: public partial class Worker

   2: {

   3:     public int ID_Bearbeiter { get; set; }

   4:     //some properties

   5:     public int deleted_from { get; set; }

   6:     public Nullable<System.DateTime> purge_date { get; set; }

   7:     public bool isDeleted { get; set; }

   8: }

 

Second part of the partial worker implementation in a separate file (don’t adapt the auto generated class!)

   1: public partial class worker : IHavePurgeDate 

   2: {

   3:     public void SetPurgeDate()

   4:     {

   5:         isDeleted = true;

   6:         purge_Date = DateTime.Now;

   7:         deleted_from = currentUser.ID;

   8:     }

   9: }

If you use Code First engineering, you won’t need a seperate file – of course!

 

Step 3: Build your own context or extend the existing one

If you use the auto generated context of the EF, you will have to create one more partial class to extend this context. If you use you’re own implementation, you can add the following code directly to your class:

   1: public override int SaveChanges()

   2: {

   3:     HandleEntries(ChangeTracker.Entries().ToList());

   4:     return base.SaveChanges();

   5: }

   6:  

   7: internal void HandleEntries(IList<DbEntityEntry> entries)

   8: {

   9:     HandleModifiedEntries(entries);

  10:  

  11:     HandleDeletedEntries(entries);

  12:  

  13:     HandleAddedEntries(entries);

  14: }

  15:  

  16: internal void HandleAddedEntries(IEnumerable<DbEntityEntry> entries)

  17: {

  18:     var createdEntities = entries

  19:         .Where(e => e.State == EntityState.Added)

  20:         .Where(e => e.Entity is IHaveCreationDate)

  21:         .ToList();

  22:  

  23:  

  24:     foreach (var dbEntityEntry in createdEntities)

  25:     {

  26:         ((IHaveCreationDate) dbEntityEntry.Entity).SetCreationDate();

  27:     }

  28: }

  29:  

  30: internal void HandleDeletedEntries(IEnumerable<DbEntityEntry> entries)

  31: {

  32:     var deletedEntities = entries

  33:         .Where(e => e.State == EntityState.Deleted)

  34:         .Where(e => e.Entity is IHavePurgeDate)

  35:         .ToList();

  36:  

  37:     foreach (var dbEntityEntry in deletedEntities)

  38:     {

  39:         ((IHavePurgeDate) dbEntityEntry.Entity).SetPurgeDate();

  40:         dbEntityEntry.State = EntityState.Modified;

  41:     }

  42: }

  43:  

  44: internal void HandleModifiedEntries(IEnumerable<DbEntityEntry> entries)

  45: {

  46:     var modifiedEntities = entries

  47:         .Where(e => e.State == EntityState.Modified)

  48:         .Where(e => e.Entity is IHaveModificationDate)

  49:         .ToList();

  50:  

  51:     foreach (var dbEntityEntry in modifiedEntities)

  52:     {

  53:         ((IHaveModificationDate) dbEntityEntry.Entity).SetModificationDate();

  54:     }

  55: }

 

That’s all. Be aware of two more things:

  • This code sample works with a DbContext of EF 4.1, but you can also use the ObjectStateManager of the ObjectContext in EF 1.0/4.0.
  • The order of handling modification and creating/deletion depends on your intended use.

Meine tägliche Portion Git

Wir haben kürzlich von Subversion auf Git gewechselt, sodass ich täglich Neues lerne. Jeder Entwickler kennt es: Man möchte etwas testen und legt sich dazu einen neuen Branch an. Auf diesem entwickelt man dann seine Änderung/ sein Feature bis man das Ergebnis wieder in den Master Branch mergen will. Genau das nehme ich nun als Ausgangssituation:

Zuerst lasse ich mir nochmal alle Branches auflisten:

  • git branch –a

image

 

Ich habe den neuen Code auf dem Branch ‘PersistenceRefactoring’ entwickelt. Nachdem ich alle Änderungen eingecheckt habe, wechsle ich auf den Master Branch zurück:

  • git checkout master

Danach aktualisiere ich mir erst einmal meine lokale Version über:

  • git pull

In der Regel sollte hier ein FastForward möglich sein. Nun wird gemergt:

  • git merge PersistenceRefactoring

Idealerweise könnt ihr mergen ohne Konflikte zu bekommen. Alternativ könnt ihr beim Merge auch angeben, welche Seite gewinnt (in diesem Beispiel mein Developer Branch):

  • git –s recursive –X theirs PersistenceRefactoring

image

Database First Walkthrough with Entity Framework 4.0

This is just a step by step walkthrough for the database approach with the Entity Framework 4.0, which means that i am using the “old” ObjectContext instead of the “new” EF 4.1 DbContext.

Create a new Console Project

image

 

Add a new Item to your project. Take the “ADO.NET Entity Data Model” template. Choose your prefered name. In my case i take myheco because i want to create an model for a database called myheco.

image

 

Choose “Generate from database” in the upcoming window

image

 

Next, choose your connection. In my example, i decide to save the connection settings in the app.config with the name “myhecoEntities”. This will be name for your context in your code if you don’t create your own implementation of the ObjectContext!

image

 

Choose your tables, views and stored Procedures you want to use and set your prefered options

image

 

Take a look at the Solution. It should look like this

image

 

Let’s try to use our OR-Mapper with LINQ-To-Entities

   1: static void Main(string[] args)

   2: {

   3:     using (var context = new myhecoEntities())

   4:     {

   5:         var item = (from users in context.Users

   6:                     where users.Name.StartsWith("Uli")

   7:                     select users).FirstOrDefault();

   8:  

   9:         if (item != null) Console.WriteLine(item.Name);

  10:     }

  11:  

  12:     Console.ReadKey();

  13: }

 

image

 

If you make changes to your Database Schema, you’ll need to update your model. You can do this by opening the Entity Data Model file (edmx) with a double click. Right click on an empty space and choose “Update Model from Database”

image

 

Choose the “Refresh”-Tab on the upcoming dialog and press “Finish”.

image

Now it depends on your database changes you’ve made if your solution still compiles.

Quellen zum Entity Framework Vortrag

Hier ein Überblick zu nützlichen Quellen rund um meinen Vortrag gestern auf der SQLPass und darüber hinaus.

 

Grundsätzlich gibt es folgende 3 Ansätze, um mit dem Entity Framework als OR-Mapper zu entwickeln:

Database First (Reverse Engineering): Aus der vorhandenen Datenbank wird das Entity Data Model (edmx) und der Code (z.B. die Entitäten) generiert. Verfügbar ist der Ansatz seit der ersten Stunde mit Version 1 im .NET Framework 3.5 SP1. Eine Anleitung dazu findet ihr hier.

Model First (Forward Engineering): Eine Anleitung dazu gibt es hier bzw. für Version 4.1 mit dem DbContext hier. Achtung: Out of the box wird keine Unterstützung für DB Versionierung bzw. Migration angeboten. Das erzeugte T-SQL macht immer ein Drop der Daten! Mit VS2010 Premium oder Ultimate gibt es die Funktion “Schema Compare”im Menüpunkt “Data”. Außerdem gibt es noch in der Visual Studio Gallery das “Entity Designer Database Generation Power Pack”, was neue T4-Vorlagen für besagtes Problem mitbringt. Keine der beiden Möglichkeiten wurden von mir vorgestellt oder bisher selbst getestet! Model First ist seit NET Framework 4 verfügbar (entspricht auch Entity Framework Version 4).

Code First: Ist seit Version 4.1 des Entity Frameworks verfügbar, welches aktuell über NuGet bezogen werden kann. 4.1 wurde zwar als Go Live Version mit Support veröffentlicht, allerdings haben sich Bugs eingeschlichen. Darüber hinaus fehlt es noch am ein oder anderen Ende. Folgende 2 Artikel bieten die wichtigsten Informationen: Artikel 1 und Artikel 2. Weiterführende Links sind noch die Möglichkeit zum Überschreiben der Konventionen im Code oder per Annotationen. Den Walkthrough für Code First gibt es hier. Achtung: Zusätzlich zu den ursprünglichen Klassen ObjectContext und ObjectSet (besser IObjectSet verwenden) gibt es jetzt DbContext und DbSet (besser IDbSet verwenden).

 

Es folgen noch ein paar weitere Links zu angesprochenen Themen:

 

Wie man eine testbare und somit gute Architektur basierenden auf dem EF aufbaut, zeigt der folgende, sehr empfehlenswerte Artikel von Scott Allen:

Testability and Entity Framework 4.0

Hierzu werde ich in nächster Zeit noch diverse Blogposts veröffentlichen, da ich Alternativen zu dem ein oder anderen Punkt aufzeigen will. Unter anderem wird das Open Closed Principle in der UnitOfWork verletzt und die Queries werden in der kompletten Anwendungsarchitektur verstreut.

Zu guter Letzt noch für die dotnet Pro Abonnementen unter euch: Im März hat eine 7-teilige Serie über das Entity Framework begonnen, von denen ich v.a. die Teile 1,4 und 5 empfehlen kann. Außerdem hat sich Patrick A. Lorenz in der 7.2011 im Artikel “Erst coden, dann fragen!” mit dem Code First Ansatz befasst.

%d Bloggern gefällt das: