<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.aspnetzone.de/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jürgen Gutsch : Architektur</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx</link><description>Ordnungsbegriffe: Architektur</description><dc:language /><generator>CommunityServer 2.1 SP2 (Build: 61120.2)</generator><item><title>Ein Blick auf das Entity Framework 4</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2012/01/03/ein-blick-auf-das-entity-framework-4.aspx</link><pubDate>Tue, 03 Jan 2012 21:18:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:223497</guid><dc:creator>Jürgen Gutsch</dc:creator><slash:comments>0</slash:comments><comments>http://www.aspnetzone.de/blogs/juergengutsch/comments/223497.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/juergengutsch/commentrss.aspx?PostID=223497</wfw:commentRss><wfw:comment>http://www.aspnetzone.de/blogs/juergengutsch/rsscomments.aspx?PostID=223497</wfw:comment><description>&lt;p&gt;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.&lt;/p&gt;  &lt;p&gt;Üblicherweise halte ich meine Entities in einem Projekt, das von allen anderen Projekten referenziert wird, die mit diesen Entities arbeiten. Mit &lt;a href="http://nuget.org/packages/NHibernate"&gt;NHibernate&lt;/a&gt; ist das auch problemlos möglich.&lt;/p&gt;  &lt;p&gt;BTW: Ich bin ein großer Fan von NHibernate und nutze diesen OR-Mapper bisher in fast jedem großen Projekt.&lt;/p&gt;  &lt;p&gt;Ich möchte also meine Entities wie folgt aufbauen:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; Customer : EntityBase   &lt;br /&gt;{    &lt;br /&gt;    [StringLength(150)]    &lt;br /&gt;    [Required]    &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; Name { get; set; }  &lt;br /&gt;    [StringLength(100)]   &lt;br /&gt;    [Required]    &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; Street { get; set; }    &lt;br /&gt;    &lt;br /&gt;    [StringLength(5)]    &lt;br /&gt;    [Required]    &lt;br /&gt;    [RegularExpression(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"^[0-9]{4,5}$"&lt;/span&gt;)]    &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; Postalcode { get; set; }    &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;EntityBase ist eine Basisklasse, welche die Id bereitstellt, Equals überschreibt, etc. Die hier sichtbaren Attribute stammen von den DataAnnotations und werden zur Validierung genutzt.&lt;/p&gt;  &lt;p&gt;Würde ich jetzt das EF wie gewohnt einsetzen, müsste ich z. B. per &lt;a href="http://nuget.org/packages/AutoMapper"&gt;AutoMapper&lt;/a&gt; von den generierten Entities auf meine Mappen. Das möchte ich nicht, bzw. müsste es mit NHibernate auch nicht tun.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;DbContext&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Nun war es heute &lt;a href="http://databinding.net"&gt;René Leupold&lt;/a&gt; der mir mit seinem Blog &lt;a href="http://databinding.net"&gt;http://databinding.net&lt;/a&gt; den entscheidenden Tipp für den DbContext gab. Mit dem DbContext ist es möglich das Entity Framework ähnlich wie NHibernate zu verwenden.&lt;/p&gt;  &lt;p&gt;Hilfreich ist auch die Artikelserie “&lt;a href="http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-1-introduction-and-model.aspx"&gt;Using DbContext in EF 4.1&lt;/a&gt;” im &lt;a href="http://blogs.msdn.com/b/adonet/"&gt;ADO.NET Team Blog&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Der DbContext ist ab EF 4.1 verfügbar. Ich selber habe mir für diese Beispiele die &lt;a href="http://nuget.org/packages/EntityFramework"&gt;EntityFramework.dll 4.2.0.0 per NuGet&lt;/a&gt; referenziert.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Das Mapping&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Was wir zusätzlich benötigen ist ein Mapping, das hier per Fluent API per C# gesetzt wird:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;internal&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; CustomerMapping : EntityTypeConfiguration&amp;lt;Customer&amp;gt;   &lt;br /&gt;{    &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; CustomerMapping()    &lt;br /&gt;    {    &lt;br /&gt;        Property(x =&amp;gt; x.Name)    &lt;br /&gt;            .HasMaxLength(200)    &lt;br /&gt;            .IsVariableLength()    &lt;br /&gt;            .IsUnicode()    &lt;br /&gt;            .IsOptional();    &lt;br /&gt;        Property(x =&amp;gt; x.Postalcode)    &lt;br /&gt;            .HasMaxLength(30)    &lt;br /&gt;            .IsVariableLength()    &lt;br /&gt;            .IsUnicode()    &lt;br /&gt;            .IsOptional();    &lt;br /&gt;    }    &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Genutzt wird die Konfiguration dann im DbContext:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; DataContext : DbContext   &lt;br /&gt;{    &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; IDbSet&amp;lt;Customer&amp;gt; Customers { get; set; }  &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;protected&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;override&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; OnModelCreating(DbModelBuilder modelBuilder)   &lt;br /&gt;    {    &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;base&lt;/span&gt;.OnModelCreating(modelBuilder);    &lt;br /&gt;        modelBuilder.Configurations.Add(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; CustomerConfig());    &lt;br /&gt;    }    &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Die Ähnlichkeit mit NHibernate ist an dieser Stelle eindeutig und ich habe meine gewünschte Trennung zwischen den Entities und dem OR-Mapper.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Die Connection&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Interessant ist, dass die Verbindung zur Datenbank über den Constructor der Basisklasse DbContext gesetzt werden kann oder aber per Konvention:&lt;/p&gt; &lt;p&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;   &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;add&lt;/span&gt; &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;name&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="DataContext"&lt;/span&gt;    &lt;br /&gt;         &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;providerName&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="System.Data.SqlClient"&lt;/span&gt;    &lt;br /&gt;         &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;connectionString&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;="Data Source=[…]"&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;/&amp;gt;&lt;/span&gt;    &lt;br /&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: Maroon;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;connectionStrings&lt;/span&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;  &lt;p&gt;Der Name des &lt;a href="http://www.connectionstrings.com/"&gt;ConnectionStrings&lt;/a&gt; muss einfach so heißen wie der entsprechende DbContext&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Benutzen&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Wenn die DB schon existiert ist das im Prinzip auch schon alles um mit den Daten zu arbeiten:&lt;/p&gt;  &lt;p&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;[Test]   &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; SetAndLoadCustomerFromDataBase()    &lt;br /&gt;{    &lt;br /&gt;    IEnumerable&amp;lt;Customer&amp;gt; customers;  &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;using&lt;/span&gt; (var context &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; DataContext())   &lt;br /&gt;    {    &lt;br /&gt;        context.Customers.Add(&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Customer    &lt;br /&gt;                                  {    &lt;br /&gt;                                      Id &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Guid.NewGuid(),    &lt;br /&gt;                                      Name &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Hallo Welt"&lt;/span&gt;,    &lt;br /&gt;                                      Street &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Hallo Street 2"&lt;/span&gt;,    &lt;br /&gt;                                      Postalcode &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"12345"&lt;/span&gt;    &lt;br /&gt;                                  });    &lt;br /&gt;        context.SaveChanges();    &lt;br /&gt;    }  &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;using&lt;/span&gt; (var context &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; DataContext())   &lt;br /&gt;    {    &lt;br /&gt;        customers &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; context.Customers.Select(c =&amp;gt; c).ToList();    &lt;br /&gt;    }  &lt;br /&gt;    Assert.That(customers.Count(), Is.GreaterThan(0));   &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Das Mapping wird erzeugt, wenn das erste mal der DataContext instanziert wird. Es wird relativ viel mit Lazy&amp;lt;T&amp;gt; gearbeitet, so dass das Debugging der ergebnislisten nicht immer ganz einfach ist.&lt;/p&gt;&amp;nbsp; &lt;p&gt;&lt;strong&gt;Demo&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Eine Demo werde ich in den nächsten Tagen hier anhängen. Die vorhandenen Projekte muss ich erst noch anonymisieren.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Fazit&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Mit dem DbContext scheint das EntityFramework doch noch ein ganz passables Werkzeug und eine ernstzunehmende Alternative zum NHibernate zu sein.&lt;/p&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=223497" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Tutorials/default.aspx">Tutorials</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Datenbank/default.aspx">Datenbank</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Tipps%20und%20Tricks/default.aspx">Tipps und Tricks</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Tools/default.aspx">Tools</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx">Architektur</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/O_2F00_R-Mapping/default.aspx">O/R-Mapping</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Entity%20Framework/default.aspx">Entity Framework</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Lazy_2600_lt_3B00_T_2600_gt_3B00_/default.aspx">Lazy&amp;lt;T&amp;gt;</category></item><item><title>Best Practices: Fehlerbehandlung</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/08/19/best-practices-fehlerbehandlung.aspx</link><pubDate>Thu, 19 Aug 2010 08:42:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:218527</guid><dc:creator>Jürgen Gutsch</dc:creator><slash:comments>11</slash:comments><comments>http://www.aspnetzone.de/blogs/juergengutsch/comments/218527.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/juergengutsch/commentrss.aspx?PostID=218527</wfw:commentRss><wfw:comment>http://www.aspnetzone.de/blogs/juergengutsch/rsscomments.aspx?PostID=218527</wfw:comment><description>&lt;P&gt;In der Vergangenheit habe ich in vielen Projekten, vielen Anwendungen und auch hier im Forum immer wieder die gleichen Fehler bei der Fehlerbehandlung gesehen, was mich dazu veranlasst diesen Beitrag hier zu schreiben.&lt;/P&gt;
&lt;P&gt;Im Grunde ist es immer folgender Fehler der beim Try&amp;amp;Catch gemacht wird:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;{ &lt;br /&gt;    [&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;do&lt;/span&gt; some errors] &lt;br /&gt;} &lt;br /&gt;Catch (Exception ex) &lt;br /&gt;{ &lt;br /&gt;    log.Error(“Meine super duper Fehlermeldung”); &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt; ex; &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Das ist dann keine Fehlerbehandlung, sondern eher Fehler verstecken!&lt;/P&gt;
&lt;P&gt;Oftmals wird dieses Konstrukt (“Fehlerbehandlung” mochte ich es nicht nennen) in jeder Methode genutzt die aufgerufen wird. Das hat dann den Effekt, dass dieses Konstrukt logisch wie folgt verschachtelt wird:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;       { &lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;           { &lt;br /&gt;                [&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;do&lt;/span&gt; some errors] &lt;br /&gt;          } &lt;br /&gt;           Catch (Exception ex) &lt;br /&gt;            { &lt;br /&gt;                log.Error(“Meine erste super duper Fehlermeldung”); &lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt; ex; &lt;br /&gt;           } &lt;br /&gt;       } &lt;br /&gt;        Catch (Exception ex) &lt;br /&gt;        { &lt;br /&gt;            log.Error(“Meine zweite super duper Fehlermeldung”); &lt;br /&gt;           &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt; ex; &lt;br /&gt;       } &lt;br /&gt;    } &lt;br /&gt;    Catch (Exception ex) &lt;br /&gt;    { &lt;br /&gt;       log.Error(“Meine dritte super duper Fehlermeldung”); &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt; ex; &lt;br /&gt;    } &lt;br /&gt;} &lt;br /&gt;Catch (Exception ex) &lt;br /&gt;{ &lt;br /&gt;    log.Error(“Meine vierte super duper Fehlermeldung”); &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt; ex; &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Oftmals wird wenigstens die aktuelle Exception dem Logger übergeben:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Catch (Exception ex) &lt;br /&gt;{ &lt;br /&gt;    log.Error(“Meine vierte super duper Fehlermeldung”, ex); &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt; ex; &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Aber auch das ist nur die halbe Miete.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Was soll da falsch sein ?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Schauen wir uns nochmal das erst Stück Code an. Angenommen es passiert ein Fehler und das Programm, springt in den Catch-Teil. Jetzt geht der Unsinn los:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Es wird eine Unsinnige Fehlermeldung ausgegeben! &lt;BR&gt;Warum? &lt;BR&gt;Falls die Meldung noch relevant sein sollte, enthält sie keine weiteren Informationen zu der eigentlichen Exception. Im Normalfall wurde der Code allerdings im Laufe der projektphase immer wieder geändert, was zur Folge hat, das die Nachricht längst nicht mehr stimmt oder es gibt inzwischen mehrere mögliche Fehlerquellen. 
&lt;LI&gt;throw ex ist der nächste grobe Fehler: es wird zwar die selbe Exception noch einmal geworfen, mit der selben Fehlermeldung, allerdings wird der immens Wichtige StackTrace abgeschnitten (“breaking the stack”). Der StackTrace beginnt ab der Methode in der throw ex aufgerufen wird. Sollte der Fehler in einer aufgerufenen Komponente auftauchen, kann das nicht mehr ermittelt werden. Es wird immer so aussehen, als wäre der Fehler in der aktuelle Methode aufgetreten, und zwar genau dort, wo thro ex aufgerufen worden ist. Genauso wie der StackTrace geht auch die InnerEception verloren (Danke an &lt;A href="http://aspnetzone.de/blogs/peterbucher/default.aspx"&gt;Peter&lt;/A&gt; für den Hinweis.)
&lt;LI&gt;Selbst wenn die Exception an den Logger übergeben wird ist die Fehlerbehandlung unvollständig, denn es wird nur ein unvollständiger StackTrace gelogt. &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Im Falle der verschachtelten Try&amp;amp;Catches sieht das so aus, dass 1. keine relevanten Fehlerinformationen geloggt werden und 2. jedes Mal der StackTrace bei jedem Catch von neuem beginnt.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Diese Fehlerbehandlung ist somit keine, sondern eine Selbsttäuschung.&lt;/STRONG&gt; &lt;/P&gt;
&lt;P&gt;Das wird man spätestens dann merken, wenn man als Entwickler vom Support die Meldung über einen Fehler bekommt und dann das Log-File analysieren muss. Ich wette das viele Fehler nicht per Log-File gefunden werden können.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Was ist zu tun?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Im ersten Schritt sollten alle throw ex Aufrufe durch ein einfaches throw ersetzt werden. Das führt dazu, dass die aufgetretene Exception genau so wie sie ist, nach “oben” weitergeleitet wird. Dann sollte das Logging angepasst werden: Bei einem einfachen Try&amp;amp;Catch sollte das Logging – wenn möglich – so geändert werden, dass die Exception an den Logger übergeben wird (Die meisten Logger sollten das Unterstützen):&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;{ &lt;br /&gt;    [&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;do&lt;/span&gt; some errors] &lt;br /&gt;} &lt;br /&gt;Catch (Exception ex) &lt;br /&gt;{ &lt;br /&gt;    log.Error(ex); &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt;; &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Im Fall der Verschachtelten Try&amp;amp;Catches wird nun noch an jeder Stelle in das Log geschrieben. Das ist nicht sinnvoll, das dadurch das Log sehr groß werden kann und die Informationen mehrfach im Log vorhanden sind. Es sollte also nur an einer Stelle geloggt werden und zwar am besten ganz oben, beim letzten Try&amp;amp;Catch. &lt;/P&gt;
&lt;P&gt;In ASP.NET kann das sogar in der global.asax bei Application_Error gemacht werden.&lt;/P&gt;
&lt;P&gt;Die verschachtelten TryCatches sehen dann logisch wie folgt aus:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;       { &lt;br /&gt;           &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;try&lt;/span&gt; &lt;br /&gt;           { &lt;br /&gt;                [&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;do&lt;/span&gt; some errors] &lt;br /&gt;           } &lt;br /&gt;           Catch (Exception ex) &lt;br /&gt;           { &lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt;; &lt;br /&gt;           } &lt;br /&gt;        } &lt;br /&gt;        Catch (Exception ex) &lt;br /&gt;        { &lt;br /&gt;           &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt;; &lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;    Catch (Exception ex) &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt;; &lt;br /&gt;    } &lt;br /&gt;} &lt;br /&gt;Catch (Exception ex) &lt;br /&gt;{ &lt;br /&gt;    log.Error(ex); &lt;br /&gt;    HandleTheException(); &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Im letzten Catch wird dann die eigentliche Fehlerbehandlung gemacht: Es wird dem Benutzer eine sinnvolle Meldung ausgegeben (Nicht die Fehlermeldung, mit der kann der Benutzer nichts anfangen!)&lt;/P&gt;
&lt;P&gt;Nach diesem Refactoring, sollte man sich&amp;nbsp; fragen welche Try&amp;amp;Catches dann noch Sinn machen, wen nichts anderes Passiert, als die Exceptions durchzureichen. Ich bin ganz sicher, dass man einige nun Entfernen könnte.&lt;/P&gt;
&lt;P&gt;Generell sollte man nicht grundlos alle möglichen Fehler abfangen, sondern in erster Linie Fehler vermeiden. Natürlich gibt es Stellen, bei denen man Fehler nicht Verhindern kann, das ist immer dann der Fall, wenn man aus seiner Anwendung raus auf etwas zugreift: Datenbank und Dateizugriffe, Web- und Webservice-Zugriffe, COM, etc.&lt;/P&gt;
&lt;P&gt;Auf diese Art hat man nun schon mal eine relativ saubere Fehlerbehandlung. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Aber es geht immer noch besser:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;An Stellen, an denen mögliche Fehler nicht verhindert werden können, können diese abgefangen und mit einer eigenen Exception nach “oben” weitergeben werden. Die ursprüngliche Exception wird dabei als InnerException mitgegeben:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Catch (Exception ex) &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;throw&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; MyVeryOwnHttpException(ex) &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;So kann man in der Darstellungsschicht individuell auf die Fehler reagieren und dem Benutzer einen entsprechenden Hinweis geben:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Catch (MyVeryOwnHttpException ex) &lt;br /&gt;{ &lt;br /&gt;    log.Error(ex.InnerException); &lt;br /&gt;    HandleTheVeryOwnHttpException(“Die Verbindung zum Server konnte nicht hergestellt werden.\n Bitte prüfen Sie ob Sie mit dem Internet Verbunden sind.\nUnd so weiter und so fort”, ex); &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Man kann so spezielle Arten von Ausnahmen zusammenfassen und entsprechend drauf reagieren. Es ist dem Anwender in der Regel egal, was der genaue Fehler ist. Ob das jetzt ein Verbindungsfehler ist oder der Server einen Fehler zurückgibt ist egal. Wichtig ist, dass in diesem Fall die Anwendung nicht mit dem Server kommunizieren kann.&lt;/P&gt;
&lt;P&gt;In der Log-File steht auf jeden Fall der konkrete Fehler mit dem kompletten StackTrace und die Fehlersuche wird dadurch wesentlich vereinfacht.&lt;/P&gt;
&lt;DIV style="TEXT-ALIGN:left;PADDING-BOTTOM:4px;MARGIN:0px;PADDING-LEFT:4px;PADDING-RIGHT:4px;PADDING-TOP:4px;" class=wlWriterHeaderFooter&gt;&lt;A href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/08/19/best-practices-fehlerbehandlung.aspx"&gt;&lt;IMG border=0 alt="DotNetKicks-DE Image" src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/08/19/best-practices-fehlerbehandlung.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=218527" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Tipps%20und%20Tricks/default.aspx">Tipps und Tricks</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/.NET/default.aspx">.NET</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx">Architektur</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Exceptions/default.aspx">Exceptions</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Exception%20Handling/default.aspx">Exception Handling</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Fehler/default.aspx">Fehler</category></item><item><title>Event Based Components</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/08/18/event-based-components.aspx</link><pubDate>Wed, 18 Aug 2010 20:22:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:218522</guid><dc:creator>Jürgen Gutsch</dc:creator><slash:comments>1</slash:comments><comments>http://www.aspnetzone.de/blogs/juergengutsch/comments/218522.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/juergengutsch/commentrss.aspx?PostID=218522</wfw:commentRss><wfw:comment>http://www.aspnetzone.de/blogs/juergengutsch/rsscomments.aspx?PostID=218522</wfw:comment><description>&lt;P&gt;In den vergangen Monaten habe ich einiges theoretisches über Event Based Components (kurz EBCs) gelesen. Das meiste von Ralf Westphal, in &lt;A href="http://ralfw.blogspot.com/search/label/Event-based%20Components"&gt;seinem Blog&lt;/A&gt; oder aus seiner Feder in der &lt;A href="http://www.dotnetpro.de/"&gt;dotnetpro&lt;/A&gt;. Auch Golo Roden schrieb in seinem Blog &lt;A href="http://www.des-eisbaeren-blog.de/?tag=/event-based+components"&gt;über das Thema&lt;/A&gt;. &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Verwirrung&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Angespornt durch die Beiträge habe ich in den letzten Wochen selber versucht EBCs zu schreiben und zu entwickeln und bin zuerst gescheitert. Sobald ich die ersten Komponenten geschrieben und “zusammengesteckt” hatte, verlor ich relativ schnell den Überblick über die Komponenten und deren Verbindungen. &lt;/P&gt;
&lt;P&gt;Woran lag das?&lt;/P&gt;
&lt;P&gt;Golo wies mich auf die fehlerhafte Benennung der Events in Ralf Westphals Beispielen hin, die entgegen dem .NET Framework mit dem Präfix “On” begannen.&lt;/P&gt;
&lt;P&gt;Ich habe also von vorne begonnen und die Events wie im .NET-Framework üblich benannt. &lt;/P&gt;
&lt;P&gt;Beispiel:&lt;/P&gt;
&lt;P&gt;public event Action&amp;lt;Customer&amp;gt; &lt;STRONG&gt;EntitySaving&lt;/STRONG&gt; (wird vor dem Speichern ausgelöst) &lt;BR&gt;public event Action&amp;lt;Customer&amp;gt; &lt;STRONG&gt;EntitySaved&lt;/STRONG&gt; (wird nach den Speichern ausgelöst)&lt;/P&gt;
&lt;P&gt;Und siehe da: die Verwirrung war beseitigt :-)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Vorteile&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Die Vorteile der EBCs sind klar und wurden in den oben genannten Beiträgen auch oft genug angesprochen. Die zwei größten Vorteile sind – aus meiner Sicht – zum einen die isolierte Testbarkeit der Komponenten und die flexible Möglichkeit die Komponenten zusammenzuführen.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Refactoring&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In den letzten Wochen habe ich also meinen angehenden Lizenz-Manager, einem großen Refactoring unterzogen und auf EBCs umgebaut. Ich habe allerdings vorerst&amp;nbsp;meine Service-Klassen nicht komplett auseinandergerissen. Also nicht fürs Speichern, Löschen und Lesen separate Komponenten gebaut (das wäre dann der nächste schritt), sondern es bei jeweils einer Komponente mit standardmäßig drei Input- und drei Output-Pins belassen. Ich habe lediglich die generische Validierung komplett entkoppelt und dafür eine weitere Komponente angelegt, die vor jedem Speichern “eingesteckt” werden kann.&lt;/P&gt;
&lt;P&gt;Die vorhandenen Unit-Tests musste ich leicht anpassen. Die Tests für die Servies, die hauptsächlich die Validierung getestet haben&amp;nbsp;konnte ich entfernen und in die Test für die Validator-Komponente aufnehmen. Die Tests sind alle kleiner geworden, da Abhängigkeiten gar nicht mehr berücksichtigt werden müssen, wenn sie nicht zusammengesteckt worden sind. Beispiel: Die Service-Methode zum Speichern, muss keine Validierung mehr testen. Und die Tests der Validierung ist unabhängig vom Speichervorgang.&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;[TestFixture] &lt;br /&gt;[Category(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"GO.LicenceManager.Services.ModelValidator"&lt;/span&gt;)] &lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; Wenn_ein_Kunde_validiert_wird &lt;br /&gt;{ &lt;br /&gt;    [Test] &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; darf_der_Vorname_nicht_fehlen() &lt;br /&gt;    { &lt;br /&gt;        Customer customer &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Customer &lt;br /&gt;                                { &lt;br /&gt;                                    [….] &lt;br /&gt;                                }; &lt;br /&gt;&lt;br /&gt;        IModelValidator&amp;lt;Customer&amp;gt; modelValidator &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; ModelValidator&amp;lt;Customer&amp;gt;(); &lt;br /&gt;        Assert.Throws&amp;lt;PropertyNotSetException&amp;lt;Customer&amp;gt;&amp;gt;( &lt;br /&gt;            () =&amp;gt; modelValidator.Validate(customer), &lt;br /&gt;            &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"'Name' must not be null or empty"&lt;/span&gt;); &lt;br /&gt;    } &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; ModelValidator&amp;lt;T&amp;gt; : IModelValidator&amp;lt;T&amp;gt; where T : IEntity &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Validate(T model) &lt;br /&gt;    { &lt;br /&gt;        Type type &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;typeof&lt;/span&gt;(T);  &lt;br /&gt;        IEnumerable&amp;lt;PropertyInfo&amp;gt; propertyInfos &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; type &lt;br /&gt;                .GetProperties(BindingFlags.Public &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;|&lt;/span&gt; BindingFlags.Instance);  &lt;br /&gt;        [….] &lt;br /&gt;    } &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; CustomerService : ICustomerService &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;readonly&lt;/span&gt; ICustomerRepository _customerRepository;  &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; CustomerService(ICustomerRepository customerRepository) &lt;br /&gt;    { &lt;br /&gt;        _customerRepository &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; customerRepository; &lt;br /&gt;    }  &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; Save(Customer customer) &lt;br /&gt;    { &lt;br /&gt;       OnEntitySaving(customer);  &lt;br /&gt;       &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(customer.Id==Guid.Empty) &lt;br /&gt;       { &lt;br /&gt;           customer.Id &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Guid.NewGuid(); &lt;br /&gt;       }  &lt;br /&gt;        _customerRepository.Save(customer); &lt;br /&gt;    }  &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;event&lt;/span&gt; Action&amp;lt;Customer&amp;gt; EntitySaving; &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; OnEntitySaving(Customer entity) &lt;br /&gt;    { &lt;br /&gt;        var entitySaving &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; EntitySaving; &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt; (entitySaving !&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;null&lt;/span&gt;) &lt;br /&gt;        { &lt;br /&gt;            entitySaving(entity); &lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;&lt;br /&gt;    [….] &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt; &lt;/P&gt;
&lt;P&gt;Zusammenstecken:&lt;/P&gt;
&lt;P&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;Customer customer &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; Customer &lt;br /&gt;                                    { &lt;br /&gt;                                        [….] &lt;br /&gt;                                    };  &lt;br /&gt;IModelValidator&amp;lt;Customer&amp;gt; validator &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; ModelValidator&amp;lt;Customer&amp;gt;(); &lt;br /&gt;ICustomerService customerService &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; CustomerService(customerRepository); &lt;br /&gt;customerService.EntitySaving += validator.Validate; &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// &amp;lt;== zusammenstecken &lt;/span&gt;&lt;br /&gt;customerService.Save(customer);&lt;/span&gt;&lt;/code&gt;&lt;/P&gt;
&lt;P&gt;Die Tests hätten wir damit vereinfacht, die Komponenten müssen sich nicht mehr kennen und sind komplett entkoppelt. Die Komponenten müssen aber irgendwie und irgendwo zusammengeführt werden, um zu funktionieren. &lt;/P&gt;
&lt;P&gt;Die Komponenten müssen “zusammensteckt” werden. &lt;/P&gt;
&lt;P&gt;Dabei ist entweder Handarbeit und eine gute Dokumentation gefordert, oder man versucht das zu automatisieren. Ralf Westphal hat dafür einen &lt;A href="http://ebcbinder.codeplex.com/"&gt;EBC-Binder&lt;/A&gt; geschrieben, der allerdings nur funktioniert, wenn gewisse Konventionen eingehalten werden: Unter anderem müssen die Events eben mit dem Präfix “On” beginnen…&lt;/P&gt;
&lt;P&gt;Ich werde hierfür wahrscheinlich eine Art Binding-Datei anlegen die im XML-Format nicht nur das Binding selber regelt, sondern dieses&amp;nbsp;auch dokumentiert. Mal sehen, was sich so machen lässt :-)&lt;/P&gt;
&lt;P&gt;Vorerst werde ich im Lizenz-Manager allerdings noch die Repositories und die verschiedenen Views implementieren müssen. Bis zur &lt;A href="http://www.seesharpparty.de/"&gt;See# Party&lt;/A&gt; werde ich wohl aber nicht mehr dazu kommen…&lt;/P&gt;
&lt;DIV style="TEXT-ALIGN:left;PADDING-BOTTOM:4px;MARGIN:0px;PADDING-LEFT:4px;PADDING-RIGHT:4px;PADDING-TOP:4px;" class=wlWriterHeaderFooter&gt;&lt;A href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/08/18/event-based-components.aspx"&gt;&lt;IMG border=0 alt="DotNetKicks-DE Image" src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/08/18/event-based-components.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=218522" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Tipps%20und%20Tricks/default.aspx">Tipps und Tricks</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Refactoring/default.aspx">Refactoring</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Clean%20Code/default.aspx">Clean Code</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Entwicklung/default.aspx">Entwicklung</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx">Architektur</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Events/default.aspx">Events</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Event%20Based%20Components/default.aspx">Event Based Components</category></item><item><title>Dependency Inection mit LightCore im dot.NET Magazin</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/05/05/dependency-inection-mit-lightcore-im-net-magazin.aspx</link><pubDate>Wed, 05 May 2010 09:51:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:217124</guid><dc:creator>Jürgen Gutsch</dc:creator><slash:comments>3</slash:comments><comments>http://www.aspnetzone.de/blogs/juergengutsch/comments/217124.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/juergengutsch/commentrss.aspx?PostID=217124</wfw:commentRss><wfw:comment>http://www.aspnetzone.de/blogs/juergengutsch/rsscomments.aspx?PostID=217124</wfw:comment><description>&lt;P&gt;&lt;A href="http://it-republik.de/dotnet/dotnet-magazin-ausgaben/IronPython-000394.html"&gt;&lt;IMG style="PADDING-BOTTOM:5px;WIDTH:339px;PADDING-RIGHT:5px;HEIGHT:482px;" border=0 alt="" align=left src="http://www.aspnetzone.de/photos/juergengutsch/images/217121/original.aspx"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Ganz stolz kann ich heute mal folgendes schreiben: &lt;/P&gt;
&lt;P&gt;Mit dem Artikel “&lt;STRONG&gt;Keine Sorge, es piekst nur ganz kurz – Dependency Injection mit LightCore&lt;/STRONG&gt;” ist mein erster Artikel in einer deutschsprachigen Fachzeitschrift erschienen. &lt;/P&gt;
&lt;P&gt;Zu finden ist der Artikel in der &lt;A href="http://it-republik.de/dotnet/dotnet-magazin-ausgaben/IronPython-000394.html"&gt;Ausgabe 6.2010 des &lt;STRONG&gt;dot.NET Magazins&lt;/STRONG&gt;&lt;/A&gt;, welche die meisten Abonnenten bereits in der Hand halten sollten.&lt;/P&gt;
&lt;P&gt;In diesem Artikel beschreibe ich kurz das Dependency Injection Pattern und vor allem die einfache Umsetzung des Patterns mit &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/default.aspx"&gt;Peter Buchers&lt;/A&gt; Dependency Injection Container &lt;A href="http://lightcore.peterbucher.ch/"&gt;LightCore&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;Übrigens gibt es LightCore auch auf FaceBook und Twitter: &lt;BR&gt;FaceBook Seite: &lt;A href="http://www.facebook.com/pages/LightCore/"&gt;http://www.facebook.com/pages/LightCore/&lt;/A&gt; &lt;BR&gt;Twitter: &lt;A href="http://twitter.com/lightcore"&gt;http://twitter.com/lightcore&lt;/A&gt;&lt;/P&gt;
&lt;DIV style="TEXT-ALIGN:left;PADDING-BOTTOM:4px;MARGIN:0px;PADDING-LEFT:4px;PADDING-RIGHT:4px;PADDING-TOP:4px;" class=wlWriterHeaderFooter&gt;&lt;A href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/05/05/dependency-inection-mit-lightcore-im-net-magazin.aspx"&gt;&lt;IMG border=0 alt="DotNetKicks-DE Image" src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/05/05/dependency-inection-mit-lightcore-im-net-magazin.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=217124" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Wissenswertes/default.aspx">Wissenswertes</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Neuigkeiten/default.aspx">Neuigkeiten</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/LightCore/default.aspx">LightCore</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/IoC/default.aspx">IoC</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/DI/default.aspx">DI</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx">Architektur</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/.NET%20Magazin/default.aspx">.NET Magazin</category></item><item><title>Katastrophenfall ‘NULL’?</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/05/03/katastrophenfall-null.aspx</link><pubDate>Mon, 03 May 2010 11:29:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:217105</guid><dc:creator>Jürgen Gutsch</dc:creator><slash:comments>4</slash:comments><comments>http://www.aspnetzone.de/blogs/juergengutsch/comments/217105.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/juergengutsch/commentrss.aspx?PostID=217105</wfw:commentRss><wfw:comment>http://www.aspnetzone.de/blogs/juergengutsch/rsscomments.aspx?PostID=217105</wfw:comment><description>&lt;P&gt;Mit seinem Beitrag &lt;A href="http://blog.thomasbandt.de/39/2331/de/blog/kleiner-helper-fuer-linq-to-sql-tolistordefault-update.html"&gt;Kleiner Helper für Linq to Sql: ToListOrDefault() &lt;/A&gt;hat &lt;A href="http://blog.thomasbandt.de"&gt;Thomas Bandt&lt;/A&gt; am Wochenende eine Diskussion zum Thema “Null als Rückgabewert” angestoßen (man beachte die Kommentare). Wie nicht anders zu erwarten (:-P), wurde die Diskussion natürlich auch von &lt;A href="http://www.ralfw.de/"&gt;Ralf Westphal&lt;/A&gt; aufgenommen: &lt;A href="http://ralfw.blogspot.com/2010/05/null-oder-nicht-null-das-ist-hier-die.html"&gt;Null oder nicht Null, das ist hier die Frage&lt;/A&gt; (auch hier die Kommentare beachten). &lt;/P&gt;
&lt;P&gt;Weiter ging es wieder Bei &lt;A title="Thomas Bandt" href="http://blog.thomasbandt.de/"&gt;Thomas Bandt&lt;/A&gt; mit dem Beitrag &lt;A href="http://blog.thomasbandt.de/39/2333/de/blog/null-verstaendnis.html"&gt;Null Verständnis&lt;/A&gt; der es tatsächlich auf 40 Kommentare gebracht hat. Auch &lt;A href="http://www.gmbsg.com"&gt;Ilker Cetinkaya&lt;/A&gt; konnte es sich diesmal nicht verkneifen ebenfalls etwas zu dem Thema zu schreiben: &lt;A href="http://www.gmbsg.com/null-toleranz/"&gt;Null Toleranz&lt;/A&gt;, vorauf hin Ralf schlagfertig reagierte: &lt;A href="http://ralfw.blogspot.com/2010/05/es-hilft-nichts-dass-es-darauf-ankommt.html"&gt;Es hilft nichts, dass es darauf ankommt – nicht nur beim Null-Problemo [OOP 2010]&lt;/A&gt; und Ilkers Haltung kritisierte. [Update] Ilkers Antwort folgte gestern relativ schnell: &lt;A href="http://www.gmbsg.com/kein-yin-ohne-yang-kein-null-ohne-pointer/"&gt;Kein Yin ohne Yang, kein Null ohne Pointer&lt;/A&gt;&amp;nbsp;(Auch hier bitte unbedingt die Kommentare lesen)&lt;/P&gt;
&lt;P&gt;Ein scheinbar vorläufiges Fazit zur Diskussion schreibt Thomas in seinem letzten Beitrag zum Thema Null: &lt;A href="http://blog.thomasbandt.de/39/2334/de/blog/null-erkenntnis-ganz-im-gegenteil.html"&gt;Null Erkenntnis? Ganz im Gegenteil.&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;[UPDATE] &lt;BR&gt;Eben hat sich auch der Karsten zum Thema geäußert: &lt;A href="http://www.aspextra.de/2010/05/03/handwerk-clean-vs-pragmatisch/"&gt;#Handwerk: Clean vs. pragmatisch?&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Was hier fast wie ein Sportbericht aussieht, ist ein Diskussion über ‘Null’ als Rückgabewert und über eine fehlende Regel zu dem Thema ob und wann ‘Null’ als Rückgabe erlaubt ist, oder nicht.&lt;/P&gt;
&lt;P&gt;Verschiedenste Lösungen kommen in allen Beiträgen und deren Kommentaren vor. So unter anderem:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Exception statt ‘Null’ 
&lt;LI&gt;Leere Objekte statt ‘Null’ 
&lt;LI&gt;‘Null’ nur passend zur Kategorie 
&lt;LI&gt;‘Null’ nur mit Vorsicht 
&lt;LI&gt;it depends 
&lt;LI&gt;‘Null’ im Katastrophenfall &lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Katastrophenfall ‘NULL’&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Und dieser letzte Punkt ist eigentlich der einzige, an dem ich mich wirklich anstoße:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://www.gmbsg.com"&gt;Ilker Cetinkaya&lt;/A&gt; [&lt;A title=http://www.gmbsg.com/null-toleranz/ href="http://www.gmbsg.com/null-toleranz/"&gt;http://www.gmbsg.com/null-toleranz/&lt;/A&gt;] &lt;BR&gt;Ich gebe in einigen Methoden NULL zurück. Meistens genau dann, wenn ich wirklich damit ausdrücken möchte, dass etwas katastrophales passiert ist.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Wenn etwas eine Katastrophe ist, sollte diese Katastrophe nur in wirklich unvermeidbaren Ausnahmen auftreten. In diesem Fall kann auch eine Ausnahme erzeugt werden. Ich bin in so einem Fall tatsächlich für eine Exception, statt einer ‘Null’ (Punkt 1).&lt;/P&gt;
&lt;P&gt;Als Webentwickler dagegen bin ich der Ansicht das man die Erzeugung von Exceptions unbedingt mit Vorsicht genießen sollte und nur dann einsetzen sollte, wenn es wirklich unvermeidbar ist. Den Exception Handling kostet Performance. Exceptions sollten also auch Exceptions bleiben und “exceptionally used” werden. Im Web ist es IMHO wichtiger Fehler zu vermeiden, als für jeden möglichen Fall eine neue Exception zu erzeugen. Zum Thema “Fehler vermeiden” gehört IMHO auch, das Auslösen von Exceptions vermeiden, wenn es sich irgendwie vermeiden lässt. Aus diesem Grund sollte der erste Punkt “Exceptions statt ‘Null’” ebenfalls mit Vorsicht genossen werden.&lt;/P&gt;
&lt;P&gt;Und was ‘Null’ als Rückgabewert angeht, enthalte ich mich fürs erste (was spezielle Regeln angeht) und bleibe Beobachter dieser Grundlagendiskussion. Ich bin mir einfach selber noch nicht schlüssig, was hier richtig und was falsch ist. Die Rückgabe von ’Null’ ist bequem, harmlos und tastbar, kann also nicht grundlegend falsch sein. &lt;/P&gt;
&lt;P&gt;Im Moment tendiere ich noch zu dem Punkt “it depends” ;-)&lt;/P&gt;
&lt;DIV style="TEXT-ALIGN:left;PADDING-BOTTOM:4px;MARGIN:0px;PADDING-LEFT:4px;PADDING-RIGHT:4px;PADDING-TOP:4px;" class=wlWriterHeaderFooter&gt;&lt;A href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/05/03/katastrophenfall-null.aspx"&gt;&lt;IMG border=0 alt="DotNetKicks-DE Image" src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/05/03/katastrophenfall-null.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=217105" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Wissenswertes/default.aspx">Wissenswertes</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/.NET/default.aspx">.NET</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Clean%20Code%20Developer/default.aspx">Clean Code Developer</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx">Architektur</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Diskussion/default.aspx">Diskussion</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Null/default.aspx">Null</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/R_26002300_252_3B00_ckgabe/default.aspx">R&amp;#252;ckgabe</category></item><item><title>BASTA! Tag 4: Intensions &amp; Interfaces – Making Patterns Concrete</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/02/25/basta-tag-4-intensions-interfaces-making-patterns-concrete.aspx</link><pubDate>Thu, 25 Feb 2010 08:22:18 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:216193</guid><dc:creator>Jürgen Gutsch</dc:creator><slash:comments>0</slash:comments><comments>http://www.aspnetzone.de/blogs/juergengutsch/comments/216193.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/juergengutsch/commentrss.aspx?PostID=216193</wfw:commentRss><wfw:comment>http://www.aspnetzone.de/blogs/juergengutsch/rsscomments.aspx?PostID=216193</wfw:comment><description>&lt;p&gt;Udi Dahan (&lt;a title="http://www.udidahan.com/" href="http://www.udidahan.com/"&gt;udidahan.com&lt;/a&gt;) beginnt in dieser Session mit der Beschreibung wie Software immer komplexer und komplexer werden kann und das es das Ziel sein sollte Software flexibel zu machen und flexibel zu halten.&lt;/p&gt;  &lt;p&gt;Oh man, es ist zu früh um einem englischsprachigen Sprecher, bei einem Thema über Design Patterns zu folgen &lt;strong&gt;und&lt;/strong&gt; dabei mit zu schreiben… ;-) Daher an dieser Stelle erst mal keine weiteren Infos. Ich werde am Wochenende diese sehr, sehr interessante Session in eigene Worte fassen und an dieser Stelle posten. Ich bitte das zu Entschuldigen… :-(&lt;/p&gt;&lt;div class="wlWriterHeaderFooter" style="text-align:left;margin:0px;padding:4px 4px 4px 4px;"&gt;&lt;a href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/02/25/basta-tag-4-intensions-interfaces-making-patterns-concrete.aspx"&gt;&lt;img src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2010/02/25/basta-tag-4-intensions-interfaces-making-patterns-concrete.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000" alt="DotNetKicks-DE Image" border="0" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=216193" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx">Architektur</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/BASTA_2100_/default.aspx">BASTA!</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Design%20Patterns/default.aspx">Design Patterns</category></item><item><title>LINQ und LINQ to SQL</title><link>http://www.aspnetzone.de/blogs/juergengutsch/archive/2009/12/30/linq-und-linq-to-sql.aspx</link><pubDate>Wed, 30 Dec 2009 21:28:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:215234</guid><dc:creator>Jürgen Gutsch</dc:creator><slash:comments>3</slash:comments><comments>http://www.aspnetzone.de/blogs/juergengutsch/comments/215234.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/juergengutsch/commentrss.aspx?PostID=215234</wfw:commentRss><wfw:comment>http://www.aspnetzone.de/blogs/juergengutsch/rsscomments.aspx?PostID=215234</wfw:comment><description>&lt;P&gt;Neulich erhielt ich eine E-Mail mit einigen Fragen zur Verwendung von “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;” in n-Tier-Applikationen, die ich hier anonymisiert beantworten möchte:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Wie sieht Microsoft beim Einsatz von “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;” die Machbarkeit von n-Tier-Applikationen, die über eine separate Datenzugriffsschicht verfügen?&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Da ich nicht Microsoft bin und auch kein offizielles Statement von Microsoft zu dieser Problematik kenne, kann ich diese Frage so nicht beantworten. Ich kann nur sagen, dass es Beispiel-Applikationen von Microsoft gibt, in denen durchaus “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;” innerhalb der Datenzugriffsschicht eingesetzt wird.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Wenn ich das richtig sehe, krankt “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;” bei seiner Nutzung mit .NET daran, dass ich bei der Nutzung aller automatisch generierten Objekte auf allen Ebenen der Anwendung einen Verweis auf “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;” benötige, oder?&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Wenn man die automatisch generierten Objekte in der ganzen Applikation nutzen möchte, ist das sicher so. Aufgrund von der Austauschbarkeit der Datenzugriffsschicht würde ich allerdings empfehlen diese automatisch generierten Objekte nicht über alle Schichten hinweg zu verwenden, sondern “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;” komplett in der Datenzugriffsschicht zu kapseln. &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Oder ich führe eine (aufwändig zu implementierende) Mapping-Schicht ein, in der ich die “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;”-generierten Datenklassen in anwendungsinterne Objekte übersetze.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Das wäre eine Möglichkeit, aber aus meiner Sicht nicht empfehlenswert. Ich würde bei einer klassischen 3-Schicht-Architektur eine vierte &lt;STRIKE&gt;parallele&lt;/STRIKE&gt; vertikale&amp;nbsp;Schicht einbinden, welche die Datenobjekte enthält die über alle Schichten hinweg zur Verfügung stehen sollen.&lt;/P&gt;
&lt;P&gt;Die Datenzugriffsschicht ist dann verantwortlich für das bereitstellen der Daten und das Mappen der Daten in die Datenobjekte der vierten &lt;STRIKE&gt;parallelen&lt;/STRIKE&gt; vertikalen&amp;nbsp;Schicht.&lt;/P&gt;
&lt;P&gt;Für den Fall, dass mal per “&lt;EM&gt;LINQ to XML&lt;/EM&gt;” auf eine XML-Datenbasis zugegriffen werden soll, muss so nur die Datenzugriffsschicht ausgetauscht werden.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Auch wenn ich Benutzeroberfläche (Grids, etc.) an “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;”-Results binden möchte, habe ich das Problem, dass ich damit ja die Datenlogik in die GUI ziehe, und damit die eigentlich unterste mit der eigentlich obersten Schicht verbinde...?&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Auch das ist ein Grund für die oben beschriebene &lt;STRIKE&gt;parallele&lt;/STRIKE&gt; vertikale&amp;nbsp;Anwendungsschicht. “&lt;EM&gt;LINQ to SQL&lt;/EM&gt;” ist auf diese Art komplett von den anderen Schichten entkoppelt und die Datenzugriffsschicht liefert nur die gewünschten Objekte.&lt;/P&gt;
&lt;DIV style="PADDING-BOTTOM:0px;MARGIN:0px;PADDING-LEFT:0px;PADDING-RIGHT:0px;DISPLAY:inline;FLOAT:none;PADDING-TOP:0px;" id=scid:6960CE03-38FC-44df-87D4-FA4540212B06:2212c81b-095c-4538-9922-5a27dada9d9a class=wlWriterSmartContent&gt;&lt;IMG style="WIDTH:403px;HEIGHT:286px;" alt="" src="http://www.aspnetzone.de/photos/juergengutsch/images/215233/original.aspx"&gt;&lt;/DIV&gt;
&lt;DIV style="TEXT-ALIGN:left;PADDING-BOTTOM:4px;MARGIN:0px;PADDING-LEFT:4px;PADDING-RIGHT:4px;PADDING-TOP:4px;" class=wlWriterHeaderFooter&gt;&lt;A href="http://dotnet-kicks.de/kick/?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2009/12/30/linq-und-linq-to-sql.aspx"&gt;&lt;IMG border=0 alt="DotNetKicks-DE Image" src="http://dotnet-kicks.de/Services/Images/KickItImageGenerator.ashx?url=http://www.aspnetzone.de/blogs/juergengutsch/archive/2009/12/30/linq-und-linq-to-sql.aspx&amp;amp;bgcolor=3169AD&amp;amp;fgcolor=FFFFFF&amp;amp;border=000000&amp;amp;cbgcolor=D4E1ED&amp;amp;cfgcolor=000000"&gt;&lt;/A&gt;&lt;/DIV&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=215234" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/.NET%203.5/default.aspx">.NET 3.5</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Tipps%20und%20Tricks/default.aspx">Tipps und Tricks</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/Architektur/default.aspx">Architektur</category><category domain="http://www.aspnetzone.de/blogs/juergengutsch/archive/tags/LINQtoSQL/default.aspx">LINQtoSQL</category></item></channel></rss>