February 2008 - Posts

I was reading about NHibernate mapping of the properties that have no setter, and how it's done through the backing field (reflection I assume). The setting looks like this:

<property name="Name" 
          access="nosetter.camelcase-underscore" 
          column="name" type="string" length="20" />

And then I got curious what would be that with the new C# 3.0 auto properties.

As a test I made a simple class with a simple string property that looks like this:

      private string test;
      
      public string Test
      {
        get { return test; }
        private set { test = value; }
      }

And with auto property this looks much sexier:

      public string Test { get; set; }

But what about backing field? Reflector shows the next:

    [CompilerGenerated]
    private string <Test>k__BackingField;
 
    public string Test 
    { 
         [CompilerGenerated] get; 
         private[CompilerGenerated] set; 
    }
 
t

Now I was wandering how  that should be communicated in the mapper file for NHibernate?... Googled.... nothing. Any ideas?

Pair programming is a proven technique for sharing knowledge among team members and teams. Benefits of that are felt after relatively a short period of time, boosting not just the productivity, but self-confidence of the developers (which is playing an important role even though is not admitted), and most of all, improving the maintainability of the code when it comes later. And it comes. It always comes.

But I would like to review additional alternatives to the knowledge sharing with team members (both direct team members, and those that are a part of another teams that might not come into direct contact with what your team is doing). What are the ways to share the knowledge?

From my personal experience, group lectures are in-effective. People are coming into those, hating it, and taking almost nothing valuable as they leave. Code camps are excellent, but the majority of the people who are attending those are doing it out of their own curiosity, enthusiasm, or just will to be better developer.

What I was doing in the company I work for, is a short (30-45 minutes) meetings once a week or two, hands on code. And the presenter was elected at the end to present his/her topic. IMHO this was working, but others may disagree. I think this was working for the developers who believed that it's not just a task of presenting, but a responsibility not to waste others time and let them learn from others what they would not learn on their own due to the lack of time or opportunity.

So what are you practicing if at all?

image

I was holding off using R# when it's not even in an EAP mode. But today I have had it. Uninstalled R# 3.1 for Visual Studio .NET 2008 and went to R# 4 nightly build.

Long time ago I had to deal with a case where the famous ViewState generated by WebForms was quiet heavy. This post is not going to wine about how bad ViewState is for the environment. This post is to show that even working with something big and nasty such as web forms, you still have to give a thought what are you trying to do and what is out there that can help you to accomplish the mission.

Before getting into the "solution" (well, it is a solution, but kind-of stinky if you are asking me), I would really recommend the post about what is ViewState and it's influence on your nervous system.

So what is solution - not to use ViewState :) Weak solution.

Spike and invent something - bad idea. The wheel in already invented.

Spike on WebForms implementation and learning - that's the one.

 

First we need to look at the "container" of the ViewState which is nothing but a Page. This is where one of my favourite tools for reflection is making its' big entrance - Reflector. Looking at the page, you shall see that a page has an interesting getter called "PageStatePersister".

 Page class using reflector

Digging deeper provides an insight into the intension of this property:

   1:  protected virtual PageStatePersister PageStatePersister
   2:  {
   3:      get
   4:      {
   5:          if (this._persister == null)
   6:          {
   7:              PageAdapter pageAdapter = this.PageAdapter;
   8:              if (pageAdapter != null)
   9:              {
  10:                  this._persister = pageAdapter.GetStatePersister();
  11:              }
  12:              if (this._persister == null)
  13:              {
  14:                  this._persister = 
  15:                      new HiddenFieldPageStatePersister(this);
  16:              }
  17:          }
  18:          return this._persister;
  19:      }
  20:  }

A few interesting things in particular we can learn from the code:

  1. The default state persister fro ANY page is a HiddenFieldPagePersister, the one that generates a hidden field with all the gibberish
  2. A page can have an Adapter that could potentially redefine what's the default persister for pages (bookmark this concept for a while, for people like myself, write it down on a piece of paper with a title "review this later")
  3. Regardless of the fact what persister is going to be used, this is a Template Method that acts as a Factory to return back an object that was derived from an abstract PageStatePersist class

What a world of opportunities in such a limited world of ViewState! Let's use reflection to find out what are the possibilities. And the winners are:

PageStatePersist class 

Not that much of options, but hey, we can have an option of keeping it at "home" on the server side, rather than sending to the client EVERY-SINGLE-ROUNDTRIP!

There are a few options:

  1. Act on a page level and override the Templated Method to return an instance of SessionPageStatePersister rather than HiddenFieldPageStatePersiter
  2. Create an adapter for the entire application
  3. Choose between option 1 or 2 with a custom persister class, inherited from abstract PageStatePersist

Option 3 is for your wild and kinky imagination, option 1 is too trivial, option 2 is what I would like to expand on a bit more.

So we want to reconfigure the entire web application for a different persister (Session one for the application that has lots of stuff in ViewState, and should produce a slim HTML). Adding a folder App_Browsers allows us to register different controls adapters. Page is a control as well, see for yourself:

image

In this folder, we can specify adapters per browser, or all of them (ahh, my old days of WAP development with Mobile ASP.NET are bubbling up, causing me a horror moment). Something like BrowserFile.browser file should do it - use VS.NET add new item option to add a .browser file. Then register an adapter for a page. The adapter code would be simple as this:

   1:  using System.Web.UI.Adapters;
   2:  using System.Web.UI;
   3:   
   4:  public class SesionPageStateAdapter : PageAdapter
   5:  {
   6:    public override PageStatePersister GetStatePersister()
   7:    {
   8:      return new SessionPageStatePersister(this.Page);
   9:    }
  10:  }

.browser file would be a trivial mapping guided by the Intellisense as you type:

   1:  <browsers>
   2:   <browser refID="Default">
   3:     <controlAdapters>
   4:        <adapter controlType="System.Web.UI.Page" 
   5:                 adapterType="SesionPageStateAdapter" />
   6:      </controlAdapters>
   7:     </browser>
   8:  </browsers>

Unfortunately it will not remove the ViewState completely, but it will definitely minimize it. Sometime several dozens of KB can be prevented from going back and forth. Also keep in mind that ControlState (from ASP.NET 2.0 and later) is possible contributing, and that one is not disableable.

Hopefully this helps to those who are in pain of watching hundreds of Kilobytes traveling there, taking more "page weight" than the page content itself.

I try to lower expectations in order not to be disappointed, but in this case I was asked by several individuals to address the fact that IoC container power is in the ability to "hook" implementer with the contract through an external file, leaving application code unaware of the actual implementer till the run-time, having no reference to implementers' assembly or whatsoever. I am going to expand the sample from the part 1 post to achieve that goal in a couple of days.

In the last post we left with the application with an ApplicationStartup() method that would register all implementers against the contracts they implement. That causes a serious coupling between the ConsoleApp assembly and the one that implements the XmlLogger, AssemblyTwo. This is not a good idea, especially when we want to be able to replace the implementer without touching/modifying the application itself (by recompiling it).

Solution would be to take the code found in ApplicationStartup() method out of the code and express in a form of some configuration file that container would process. By doing that, we minimize coupling of the AssemblyTwo to Core only, and completely removing coupling of ConsoleApp on AssemblyTwo.

ioc_configuration_file_1

Now ConsoleApp has only references to what it really utilizes directly.

using System;
using AssemblyOne; // IGadget
using Core.IoC;    // ILogger and Container

Next step is to describe the relationships between contracts and implementers. Something like an XML file should be ok.

ioc_configuration_file_2

Once this is place, the rest is just forcing Container to scan a file and look for Container.xml, registering all of the contracts and their implementers and passing that information back to the container for registration. To transform from a string presentation into a .NET type, I use reflection and that takes care of loading the desired assembly into memory. From there we get the type and register in container, allowing later instantiation.

The code that loads the XML file:

 

namespace Core.IoC
{
  public sealed class XmlConfiguration
  {
    private readonly string filename;

    public XmlConfiguration() : this("Container.xml")
    {
    }

    public XmlConfiguration(string filename)
    {
      this.filename = filename;
    }

    public Dictionary<Type, Type> GetAllRegistrations()
    {
      Dictionary<Type, Type> result = new Dictionary<Type, Type>();
      string fileWithPath = GetPathAndName();

      if (File.Exists(fileWithPath))
      {
        XmlReader reader = XmlTextReader.Create(fileWithPath);
        reader.MoveToContent();
        while (reader.Read())
        {
          if (reader.LocalName == "Register")
          {
            Type contract = BuildTypeFromAssemblyAndTypeName(
                                          reader.GetAttribute("Contract"));
            Type implementer = BuildTypeFromAssemblyAndTypeName(
                                       reader.GetAttribute("Implementer"));
            result.Add(contract, implementer);
          }
        }
      }

      return result;
    }

    private Type BuildTypeFromAssemblyAndTypeName(string fullTypeName)
    {
      int commaIndex = fullTypeName.IndexOf(",");
      string typeName = fullTypeName.Substring(0, commaIndex).Trim();
      string assemblyName = fullTypeName.Substring(commaIndex + 1).Trim();
      return Assembly.Load(assemblyName).GetType(typeName, false, false);
    }

    private string GetPathAndName()
    {
      string[] split =
        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, filename)
                .Split(new string[] {"\\bin\\"},
                       StringSplitOptions.RemoveEmptyEntries);
      return Path.Combine(split[0], filename);
    }
  }
}

Updated Container class will have to reflect changes:

using System;
using System.Collections.Generic;

namespace Core.IoC
{
  public class Container : IContainer
  {
    public static readonly IContainer Instance = new Container();

    private readonly Dictionary<Type, Type> container;

    private Container() : this(new XmlConfiguration())
    {
    }

    private Container(XmlConfiguration xmlConfiguration)
    {
      container = new Dictionary<Type, Type>();

      foreach (KeyValuePair<Type, Type> pair in 
                                    xmlConfiguration.GetAllRegistrations())
      {
        AddImplemeterTypeForContractType(pair.Key, pair.Value);
      }
    }

    public void AddImplementerFor<ContractType>(Type implementer)
    {
      AddImplemeterTypeForContractType(typeof (ContractType), implementer);
    }

    private void AddImplemeterTypeForContractType(Type contractType, 
                                                  Type implementerType)
    {
      container.Add(contractType, implementerType);
    }

    public ContractType GetImplementerOf<ContractType>()
    {
      return (ContractType) Activator.CreateInstance(
                              container[typeof (ContractType)]);
    }
  }
}

What we've got now? An option of specifying implementers outside of the application code. Having this, teams (team members) can split up, code, and configure an external file to do the mapping between contract and implementer  without touching the application code itself. Implementer is only coupled to the Core (where contract ILogger) is defined. The Core / AssemblyOne  / ConsoleApp know nothing about implementer, but are able to leverage it to do the work.

ioc_configuration_file_3

Next steps? Well, we could talk about chains of dependencies, parameterized constructors,  factories, etc. But this is where I am pausing and suggesting not to re-invent the wheel. Go grab some existing IoC container and pump your application to achieve it's best relying on technology that now you do not consider to be a magical anymore.

Updated code is here.

I was exposed to an interesting product from innotek called VirtualBox. If you like MS VPC or VMWare, check this one out. It's free, it's not bad (so far I was just playing with it installing Windows XP and running some applications on a quiet slow host machine). Would love to hear others comments on this one, or any other alternative that is welcomed.

In a multi layered application architecture, loosely coupled code is more than a important. It's the basic which can either help the entire project progress, or drive it down the slope to the end (in the bad meaning of the word). One of the basics to keep coupling as low as possible is Inversion of Control (IoC) container.

I will try to show how to put in place a simple version of IoC container to allow loosely coupled design. The solution will contain several projects to emulate a layered application as much as possible. The choice of console application is only driven by intent to keep it as simple as possible.

In our application we do basic logging at all layers. Logger that does it is following the next contract:

  public interface ILogger
{
void Log(string message);
}

Lets assume that the initial version of logger is implemented as a simple Console logger:

  public class ConsoleLogger : ILogger
{
public void Log(string message)
{
System.Console.WriteLine(message);
}
}

Now lets look what the layered structure looks like. The lowest layer in the stack is going to be Core. This one will contain the interfaces (such as ILogger for instance) all other layers have to consume. This is a sort of tight coupling, but it is not bad as upper layers will depend on abstraction and not concrete implementation (DIP).

ioc_layered_structure

AssemblyOne, Two, Three, and others are all potential layers you could have (and I am not necessarily insisting on having them - there should be a rational limit). ConsoleApp is the top layer that represent the application. This could be easily a Windows application or a web application.

To spice up our life, we have to implement a gadget in AssemblyOne that will follow a certain contract (IGadget) and each operation defined by the contract, has to be logged when implementation is invoked. The contract is:

  public interface IGadget
{
void TurnOn();
void TurnOff();
}

Now the implementation of the Gadget will be quiet simple:

   1:  using Core;
   2:   
   3:  namespace AssemblyOne
   4:  {
   5:    public class Gadget : IGadget
   6:    {
   7:      private readonly ILogger logger;
   8:   
   9:      public Gadget(ILogger logger)
  10:      {
  11:        this.logger = logger;
  12:      }
  13:   
  14:      // Default constructor will be discussed a bit later 
  15:      // public Gadget() {}
  16:   
  17:      public void TurnOn()
  18:      {
  19:        logger.Log("TurnOn");
  20:      }
  21:   
  22:      public void TurnOff()
  23:      {
  24:        logger.Log("TurnOff");
  25:      }
  26:    }
  27:  }

The program in the upper (ConsoleApp) layer will look this way:

   1:  using System;
   2:  using AssemblyOne;
   3:  using Core;
   4:   
   5:  namespace ConsoleApp
   6:  {
   7:    internal class Program
   8:    {
   9:      private static void Main()
  10:      {
  11:        AppCode();
  12:   
  13:        Console.WriteLine("done.");
  14:        Console.ReadLine();
  15:      }
  16:   
  17:      private static void AppCode()
  18:      {
  19:        ConsoleLogger logger = new ConsoleLogger();
  20:        Gadget gadget = new Gadget(logger);
  21:        gadget.TurnOn();
  22:        gadget.TurnOff();
  23:      }
  24:    }
  25:  }

AppCode method (lines 19-22) is what we are interested in. A few question can be raised at this point:

  1. Why logger is of type ConsoleLogger and not ILogger? Isn't this wrong?
  2. Why gadget is of type Gadget and not IGadget? Same smell?
  3. What if we need to move logger implementer to a different layer than the ConsoleApp?

These are all excellent questions. The first two are definetely a bad smell. Why? Well, because we should be really sticking to what contracts were obligating implementers, and not be even able to use the "extras" provided by contract implementers "outside" of the contract. This will eliminate any chance that an "undocumented" by contract method will extinct from existing, causing our client code to break. The third question is the one that shows that current design is not going to work - current ILogger implementer is located in ConsoleApp layer and we have to pass it as a dependency into gadget. But what if we introduce another implementation of ILogger, like XML logger, and it will live in another layer, AssemblyTwo? And what if we want to be able to create gadget without specifying logger, relying on a default one? This is where IoC container would help.

The idea behind container is simple: lower layer provides an option of registering a contract implementer, and later, retrieve that contract implementer instance, by just using the contract type. Expressing this in code would look like the next snippet:

namespace Core.IoC
{
public interface IContainer
{
// register contract implementer
void AddImplementerFor<ContractType>(Type implementer);
// retrieve contract implementer
ContractType GetImplementerOf<ContractType>();
}
}

Implementation of this contract is a subject to a separate discussion. To keep it simple, I have decided to use the simplest way out there:

   1:  using System;
   2:  using System.Collections.Generic;
   3:   
   4:  namespace Core.IoC
   5:  {
   6:    public class Container : IContainer
   7:    {
   8:      public static readonly IContainer Instance = new Container();
   9:   
  10:   
  11:      private readonly Dictionary<Type, Type> container;
  12:   
  13:      private Container()
  14:      {
  15:        container = new Dictionary<Type, Type>();
  16:      }
  17:   
  18:      public void AddImplementerFor<ContractType>(Type implementer)
  19:      {
  20:        container.Add(typeof(ContractType), implementer);
  21:      }
  22:   
  23:      public ContractType GetImplementerOf<ContractType>()
  24:      {
  25:        return 
  (ContractType)Activator.CreateInstance(container[typeof (ContractType)]);
  26:      }
  27:    }
  28:  }

Yes, the core secret is in Activator class, provided by .NET framework. No magic.

With this in hand, we can start using container all other the place, breaking the dangerous coupling. First thing first, registering contracts and their implementers for the application. This will change how we start our application:

   1:  using System;
   2:  using AssemblyOne;
   3:  using Core;
   4:  using Core.IoC;
   5:   
   6:  namespace ConsoleApp
   7:  {
   8:    internal class Program
   9:    {
  10:      private static void Main()
  11:      {
  12:        ApplicationStartup();
  13:   
  14:        AppCode();
  15:   
  16:        Console.WriteLine("done.");
  17:        Console.ReadLine();
  18:      }
  19:   
  20:      private static void ApplicationStartup()
  21:      {
  22:        Container.Instance.AddImplementerFor<ILogger>(typeof(
                                                           ConsoleLogger));
  23:        Container.Instance.AddImplementerFor<IGadget>(typeof(Gadget));
  24:      }
  25:   
  26:      private static void AppCode()
  27:      {
  28:        IGadget gadget = 
                            Container.Instance.GetImplementerOf<IGadget>();
  29:        gadget.TurnOn();
  30:        gadget.TurnOff();
  31:      }
  32:    }
  33:  }

Line 12 introduces a new (quiet old actually) concept - application startup point. In web application something like Application_Start in Global.asax would be an equivevalent. What it does is teaching the container about contracts, and who are the implementers. That way, we can get an instance of an IGadget without worrying who implements it (line 28). Also we don't need to directly inject the logger dependency, due to the fact that gadget can query for the default logger through the container. Updated logger looks like this:

   1:  using Core;
   2:  using Core.IoC;
   3:   
   4:  namespace AssemblyOne
   5:  {
   6:    public class Gadget : IGadget
   7:    {
   8:      private readonly ILogger logger;
   9:   
  10:      public Gadget(ILogger logger)
  11:      {
  12:        this.logger = logger;
  13:      }
  14:   
  15:      public Gadget() : 
                    this(Container.Instance.GetImplementerOf<ILogger>()) {}
  16:   
  17:      public void TurnOn()
  18:      {
  19:        logger.Log("TurnOn");
  20:      }
  21:   
  22:      public void TurnOff()
  23:      {
  24:        logger.Log("TurnOff");
  25:      }
  26:    }
  27:  }

Line 15 defines a default constructor that leverages container to get the default implementation of logger.

Now we will substitute the default logger by another implementer, from another assembly (AssemblyTwo) that logs information into an XML file:

   1:  using System;
   2:  using System.IO;
   3:  using System.Xml;
   4:  using Core;
   5:   
   6:  namespace AssemblyTwo
   7:  {
   8:    public class XmlLogger : ILogger
   9:    {
  10:      private readonly string fileName;
  11:   
  12:      public XmlLogger() : this("log.xml")
  13:      {
  14:      }
  15:   
  16:      public XmlLogger(string fileName)
  17:      {
  18:        this.fileName = fileName;
  19:      }
  20:   
  21:      public void Log(string message)
  22:      {
  23:        XmlDocument document = new XmlDocument();
  24:        string filePath = Path.GetFullPath(fileName);
  25:        CreateFileIfDoesntExist(filePath);
  26:        document.Load(filePath);
  27:        XmlElement root = document.DocumentElement;
  28:        XmlElement element = document.CreateElement("log");
  29:        element.SetAttribute("timestamp", 
                         DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"));
  30:        element.InnerText = message;
  31:        root.AppendChild(element);
  32:        document.Save(fileName);
  33:      }
  34:   
  35:      private void CreateFileIfDoesntExist(string filePath)
  36:      {
  37:        if (!File.Exists(filePath))
  38:        {
  39:          XmlWriter writer = XmlTextWriter.Create(fileName);
  40:          writer.WriteProcessingInstruction("xml", 
                                       "version='1.0' encoding='UTF-8'");
  41:          writer.WriteStartElement("logs");
  42:          writer.Close();
  43:        }
  44:      }
  45:    }
  46:  }

The adjustment has to be done to the startup method to register the new implementer in the container:

    private static void ApplicationStartup()
{
Container.Instance.AddImplementerFor<ILogger>(typeof(XmlLogger));
Container.Instance.AddImplementerFor<IGadget>(typeof(Gadget));
}

Now the entire system uses XML logger as a default logger:

ioc_layered_structure_container

There is a scenario when contract implementer is in an assembly that should not be referenced from the code (due to the fact that it is just not available during the development time)? Then something like an external file for container configuration can/should be used. We will have to specify the assembly name as well, so the activator would be able through the reflection to invoke constructor.

Bottom line - this is far from being perfect, but it was not intended to do the heavy lifting (though could be used to do IoC container work). My recommendation would be to understand what power it gives you and take one of the existing containers such as Windsor, Spring.NET, StructureMap, etc.

...hey, what's up with the log there? Was it working at all? See for yourself, get the code

Part 2 of this blog is here

Mr. Mo has wrote a nice post about securing collection and turning it into an immutable object. I am adding my 20 cents by reminding a great example JP Boodhoo has showed during his "Nothin But .NET" training session, leveraging ReadOnlyCollection<T> class to make a collection immutable.

Lately I am paying more and more attention to aspects of Domain Driven Development (DDD), development where code is looking more at the domain in which it is trying to resolve problem(s), rather than technologies it is using. One of the biggest headaches that you getting into when trying to adopt DDD is persistence. Normally persistence is done in Relational database such as SQL server, Oracle, or another vendor database. And this is exactly the problem - Object Oriented model vs. Relational Data model. So what is more important, a software that is written in DDD way,  that forces you to put DB on a lower priority, or DB efficiency as a priority pushing your software from Domain driven development to become a Data Driven development? If you asking me - domain is more  valuable. I will show an example that to me serves the best proof for those who still try to save the "extra round trips to DB" or "we could combine the queries and have a single call to the DB". Keep in mind, I am not going against DB efficiency, after all a sloppy data access can kill the best application out there. But having a great data access model will not make you application writing easier, on contrary.

The example is simple. The system defines Organizations. One of the views has to list all the organizations in the system with one business rule that is coming from a client as a requirement - "the default" organization has always to appear on top.

So having a list of Organizations I need to apply the rule to transform the list and pass to the view. Simple. This is where differences between Domain DD and Data DD are starting to bubble up.

Note: according to the client, default organization is setup once per application and is not changing. The development team has decided to store the default organization id (Guid) in a configuration file for simplicity.

The first code does the next:

   1:  namespace Sample
   2:  {
   3:    public class DefaultOrganizationIsOnTopBusinessRule
   4:    {
   5:      private readonly Organization defaultOrganization;
   6:      private readonly List<Organization> originalOrganizationList;
   7:   
   8:      public DefaultOrganizationIsOnTopBusinessRule(
   9:                  IEnumerable<Organization> organizations, 
  10:                  Organization defaultOrganization)
  11:      {
  12:        originalOrganizationList = new List<Organization>(organizations);
  13:        this.defaultOrganization = defaultOrganization;
  14:      }
  15:   
  16:      public IList<Organization> Apply()
  17:      {
  18:        if (originalOrganizationList.Contains(defaultOrganization))
  19:        {
  20:          List<Organization> newList = new List<Organization>();
  21:          newList.Add(originalOrganizationList
  22:                      .Find(delegate(Organization org)
  23:                      {
  24:                         return org.Equals(defaultOrganization);
  25:                      }));
  26:          newList.AddRange(originalOrganizationList
  27:                     .FindAll(delegate(Organization org)
  28:                     {
  29:                        return !org.Equals(defaultOrganization);
  30:                     }));
  31:          return newList;
  32:        }
  33:   
  34:        return originalOrganizationList;
  35:      }
  36:    }
  37:  }

The second code, does almost the same, except that it tries to "save a trip to DB" in terms of supplying just the default organization id, and not the entity. the code is:

   1:  namespace Sample
   2:  {
   3:    public class DefaultOrganizationIsOnTopBusinessRule
   4:    {
   5:      private readonly Guid defaultOrganizationGuid;
   6:      private readonly List<Organization> originalOrganizationList;
   7:   
   8:      public DefaultOrganizationIsOnTopBusinessRule(
   9:                  IEnumerable<Organization> organizations, 
  10:                  Guid defaultOrganizationGuid)
  11:      {
  12:        originalOrganizationList = new List<Organization>(organizations);
  13:        this.defaultOrganizationGuid = defaultOrganizationGuid;
  14:      }
  15:   
  16:      public IList<Organization> Apply()
  17:      {
  18:        Organization defaultOrg = originalOrganizationList
  19:                      .Find(delegate(Organization org)
  20:                      {
  21:                         return org.Guid == defaultOrganizationGuid;
  22:                      });
  23:        if (defaultOrg != null)
  24:        {
  25:          List<Organization> newList = new List<Organization>();
  26:          newList.Add(defaultOrg);
  27:          newList.AddRange(originalOrganizationList
  28:                     .FindAll(delegate(Organization org)
  29:                     {
  30:                        return org.Guid != defaultOrganizationGuid;
  31:                     }));
  32:          return newList;
  33:        }
  34:   
  35:        return originalOrganizationList;
  36:      }
  37:    }
  38:  }

but this is an illusion of "quick" and "quality" code - several reasons:

  1. Who said we need to reconstruct the default organization all the time? We can leverage caching to keep it available to us without hitting DB each time
  2. Who said that organization entity is going to be identified by a Guid in the next few iterations?
  3. We are violating encapsulation by reaching out into the internals of an entity (object) - an object should know how to do things on itself
  4. Maintainability - what is easy to understand, a code that requires an object, or a code that expects a Guid?
  5. How easy it is to break the code if rather than sending a Guid of an organization we will send a Guid of another entity type that is also identified by a Guid?

If you answer these questions and you find yourself preferring the 1st code snippet, then domain is what you care for more, and along with it maintainability of what you build. In case the second code snippet is more appealing to your heart, then DB is all you care and get ready for some serious hacks and workarounds in your code to keep it running for the sake of efficient DB access.

To finish this post, I would like to comment a few sentences from Eric Evans book:

"The goal of domain-driven design is to create better software by focusing on a model of the domain rather than the technology. By the time a developer has constructed an SQL query, passed it to a query service in the infrastructure layer, obtained a result set of table rows, pulled the necessary information out, and passed it to a constructor or FACTORY, the model focus is gone. It becomes natural to think of the objects as containers for the data that the queries provide, and the whole design shifts toward a data-processing style. The details of the technology vary, but the problem remains that the client is dealing with technology, rather than model concepts."

More Posts