Posts in category .net - page 27

Patterns of Enterprise Application Architecture

While a big fan of patterns I found the original Gang of Four (GoF) book a little dry and so had left the pattern books alone until Martin Fowler’s Patterns of Enterprise Application Architecture (PEAA), got referenced so many times on-line I gave in and purchased a copy. I’m glad I did – even if the examples are mostly in Java with the very occasional one in C#.

The patterns in the original GoF were really about the interactions between the objects themselves and whilst PEAA has some object-to-object interactions it concentrates on problems encountered in “Enterprise Applications”. This includes database mappings, transactions, web pages and concurrency.

The first half of the book provides a readable narrative and discussion of the various patterns with recommendations for when to use each and when to avoid. Part two explains each pattern in detail providing an essential reference to the patterns themselves. This mix of half-narrative and half-reference works very well and is certainly something other programming books would do well to steal.

As somebody who has been writing ‘Enterprise’ applications for some time it is interesting to see many of the problems described in neutral terms as well as the road-not-travelled alternatives and a rationale for their existence. Even if you came up with something similar yourself (and I’m sure you’ll find a few) giving it a meaningful common name makes life easier when discussing the solution with others.

A fair chunk of the book covers object-relational mapping (ORM) and it addresses most all the issues including whether to go full domain model/data mapper, active record, record set as well as the more intricate issues such as lazy loading, locking, identity map and approaches for how many tables to use for a given object.

There are a couple of issues I have with some of the patterns that don’t seem to be addressed so I’ll throw them out here:

Identity Map

The identify map’s description is

“Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them.”

There are two problems here;

  1. Objects become stale as other users perform updates that your browser/user can never see until your session terminates and thus looses your map. “Log out to see changes” is not acceptable.
  2. Resource consumption is heavy as your identity map effectively holds every object loaded in memory regardless of whether it’s used any more. Those objects may reference other objects too – combine this with a web server and you’re looking at a recipe for disaster as resources dry up.

One approach would be use develop your map using some form of weak reference mechanism. This would mean that once your code looses the last reference the object will be eligible for garbage collection and subsequent reloading from the database. This effectively kills off the secondary role as a cache but better than a web site running out of memory showing lots of old data.

Money

Martin puts forward his discussion of the Money class and while the rounding is useful in my experience a monetary amount and a currency isn’t much use without some way of getting an exchange rate to the base currency.

Lazy Load

The samples Martin provides here are not thread safe and you could easily find yourself with two different objects where you expect one. For a section on lazy loading for enterprise apps not having a double-check lock is a bit sloppy. To correct the sample on page 203 would be (I’ve also converted it to C# 2.0);

public List<Products> GetProducts() {
  if (products == null)
    lock(this)
      if (products == null)
        products = Product.FindForSupplier(GetID());
  return products;
}

Overall a very good book – I really need to get to grips with the patterns Foreign Key Mapping and Class Table Inheritance now.

[)amien

Observing changes to a List by adding events

In an attempt to get more C# and .NET content up I’m putting up some snippets I’ve put together in response to questions on some C# user support groups. Many of them are not particularly advanced but they are quite useful.

GitHub has the latest version of ObservableList</a> </p> This sample shows how to observe events on an generic IList. It does this by way of implementing the IList interface over the top of something that already supports IList to do the actual work and highlights how useful publishing the interface, IList, separate from the actual concrete class List can be for reuse. ```csharp using System; using System.Collections; using System.Collections.Generic; public class ObservableList : IList { private IList internalList; public class ListChangedEventArgs : EventArgs { public int index; public T item; public ListChangedEventArgs(int index, T item) { this.index = index; this.item = item; } } public delegate void ListChangedEventHandler(object source, ListChangedEventArgs e); public delegate void ListClearedEventHandler(object source, EventArgs e); public event ListChangedEventHandler ListChanged; public event ListClearedEventHandler ListCleared; public ObservableList() { internalList = new List(); } public ObservableList(IList list) { internalList = list; } public ObservableList(IEnumerable collection) { internalList = new List(collection); } protected virtual void OnListChanged(ListChangedEventArgs e) { if (ListChanged != null) ListChanged(this, e); } protected virtual void OnListCleared(EventArgs e) { if (ListCleared != null) ListCleared(this, e); } public int IndexOf(T item) { return internalList.IndexOf(item); } public void Insert(int index, T item) { internalList.Insert(index, item); OnListChanged(new ListChangedEventArgs(index, item)); } public void RemoveAt(int index) { T item = internalList[index]; internalList.Remove(item); OnListChanged(new ListChangedEventArgs(index, item)); } public T this[int index] { get { return internalList[index]; } set { internalList[index] = value; OnListChanged(new ListChangedEventArgs(index, value)); } } public void Add(T item) { internalList.Add(item); OnListChanged(new ListChangedEventArgs(internalList.IndexOf(item), item)); } public void Clear() { internalList.Clear(); OnListCleared(new EventArgs()); } public bool Contains(T item) { return internalList.Contains(item); } public void CopyTo(T[] array, int arrayIndex) { internalList.CopyTo(array, arrayIndex); } public int Count { get { return internalList.Count; } } public bool IsReadOnly { get { return internalList.IsReadOnly; } } public bool Remove(T item) { lock(this) { int index = internalList.IndexOf(item); if (internalList.Remove(item)) { OnListChanged(new ListChangedEventArgs(index, item)); return true; } else return false; } } public IEnumerator GetEnumerator() { return internalList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable) internalList).GetEnumerator(); } } ``` _[)amien_

First look: Applying Domain-Driven Designs and Patterns

In an attempt to quench my thirst for all things C# and having already torn through the great .NET Framework Design Guidelines and less-great Effective C# I grabbed a copy of Applying Domain-Driven Design and Patterns (With Examples in C# and .NET) by Jimmy Nilsson.

The book is obviously based around domain models but also gives some coverage to test-driven development, NHibernate, design patterns, refactoring, code-smells etc.

This is only a first-look as I’m only up to page 130 of the 500+ the tome weighs in at but here are a few observations so far.

The Impedance Mismatch Between Domain Model and Relational Database

One annoyance with the book is that is identifies and discusses problems and then offers no discussion or ideas for a solution before moving onto another topic.

A good example is this section which touches on the mismatch between the primitive types of .NET and SQL without the consideration of how/where to check this, the fact that SQL types can be null with no regard to .NET 2’s INullable, bit flags or ‘magic values’.

How to Recognize If an Application Will Be Long Lasting

Another perfect example of the previous problem. The heading asks the question but the short anecdote about how a hacked together app became mission critical fails to answer it.

Use public fields

Jimmy proposes a number of techniques that fly in the face of .NET Framework Guidelines and other solid material. This is highlighted by the phrase;

As long as the fields are both readable and write-able and no interception is needed … public fields are at least as good as properties.

Perhaps Jimmy doesn’t know that converting a field to a property later will break binary compatibility with anything using your assembly.

Expose internals for testing

…expose sub-results so they are testable

flies in the face of hiding the implementation and Jimmy does at least refer to this balance but the whole idea of exposing unnecessary details for the sake of being able to test them gives me a shudder.

Throwing aside the whole question of whether you should write unit tests that test implementation rather than interface a better solution would be to add a

#if TESTING

block to classes that really need to expose their internals to your test tools and compile with that switch set in your testing environment.

Use static factory classes!

Jimmy extracts the factory methods into a new class and but then leaves them static. A static class throws away substitutability, extension and indeed everything that makes OO great for the sake of being able to access it like a global variable.

Expose IList as read-only

On page 102 Jimmy refactors a “public IList Children” field firstly making it a read-only property and then creates a AddChild method which is fine but then how will he stop people modifying his IList? With ArrayList.ReadOnly(children) of course bemoaning how clients still see .Add etc.

Hello Jimmy, let me introduce you to IEnumerable.

Use reflection to set internal properties from Factory & Repository!

Jimmy describes how some properties should be read-only but then the Factory and Repository need to set the values. He proposes reflection.

Maybe Jimmy missed the memento pattern and dislikes the internal keyword.

Coding standards

All the code samples use _ for internal members – something that Microsoft guidelines and their FxCop tools are keen to stamp out. Besides being ugly it also reeks of the obsolete Hungarian naming prefixes.

Storybook format

The whole book is written in “I still remember”, “I worked on an application”, “After that, I tried Domain Models”… It makes for slow reading at times.

Well that about wraps it up so far.

[)amien

Extend HttpApplication with session counts and uptime

It’s sometimes useful to know or display how many people are currently using your web application and how long it’s been up for.

As web applications normally inherit from System.Web.HttpApplication we can extend this class with a common re-usable class to add the required functionality.

public class WebApplication : System.Web.HttpApplication {
    private static readonlyDateTime pStartedAt = DateTime.Now;
    private static long pSessionCount = 0;

    public WebApplication() : base() { }

    public override void Init () {
        base.Init();
        HookEventHandlers();
    }

    public static long SessionCount {
        get { return pSessionCount; }
    }

    public static DateTime StartedAt {
        get { return pStartedAt; }
    }
    public static TimeSpan Uptime {
        get { return DateTime.Now.Subtract(pStartedAt); }
    }

    private void HookEventHandlers () {
        IHttpModule httpModule = Modules["Session"];
        if (httpModule is SessionStateModule) {
            SessionStateModule sessionStateModule = ((SessionStateModule) httpModule);
            sessionStateModule.Start += new System.EventHandler(SessionStart);
            sessionStateModule.End += new System.EventHandler(SessionEnd);
        }
    }

    private void SessionStart (object sender, EventArgs e) {
        Interlocked.Increment(ref pSessionCount);
    }

    private void SessionEnd (object sender, EventArgs e) {
        Interlocked.Decrement(ref pSessionCount);
    }
}

The next step is to ensure your web application’s class – as defined by global.asax – is of the new WebApplication type. A good approach is to have your own Global.asax.cs file inherit directly from the new WebApplication;

public class App : WebApplication { ... }

Now those sessions and uptime are being tracked how do you get at them?

lblCurrentSessions.Text = WebApplication.SessionCount.ToString();
lblUptime.Text = WebApplication.Uptime.ToString();

This approach is only suitable for sites operating on a single web server.

[)amien