IEnumarable with a Count = IEnumerableList

I do Domain-Drive-Design (DDD) and one of the golder rules practically says that the domain model shouldn’t expose more necessary.

Example:

    1 public class Item

    2 {

    3     public IList<Bid> Bids

    4     {

    5         get; private set; }

    6 

    7     public Item()

    8     {

    9         Bids = new List<Bid>();

   10     }

   11 }

   12 

   13 public class Bid

   14 {

   15 }

The class Item has collection of the Bid(s). So Item can expose property IList Bids {get;}. The problem is that in case Bid has a reference to Item then it’s possible that that Bid1 whose parent item is Item1 is added to Item2. The designer of the domain model enable us to do it. This is violation of the domain model rules.

Solution: we should add method AddBid(Bid bid) {} to the class Item and change the Item’s property Bids to the following IEnumerable Bids {get;}

Fine, but what to do in case there is a logic which would like to know how many bids some item has. IEnumerable doesn’t expose such property. For such cases I create my IEnumerableList.

    1 public interface IEnumerableList<T> : IEnumerable<T>

    2 {

    3     /// <summary>

    4     /// Gets the <see cref="T"/> at the specified index.

    5     /// </summary>

    6     /// <value></value>

    7     T this[int index] { get; }

    8 

    9     /// <summary>

   10     /// Gets the count.

   11     /// </summary>

   12     /// <value>The count.</value>

   13     int Count { get; }

   14 }

and I also created the List implementation called EnumerableList:

    1 public class EnumerableList<T> : IEnumerableList<T>

    2 {

    3     private readonly IList<T> underlyingList;

    4 

    5     /// <summary>

    6     /// Initializes a new instance of the <see cref="EnumerableList&lt;T&gt;"/> class.

    7     /// </summary>

    8     /// <param name="list">The list.</param>

    9     public EnumerableList(IList<T> list)

   10     {

   11         underlyingList = list;

   12     }

   13 

   14     #region Implementation of IEnumerable

   15 

   16     /// <summary>

   17     /// Returns an enumerator that iterates through the collection.

   18     /// </summary>

   19     /// <returns>

   20     /// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.

   21     /// </returns>

   22     /// <filterpriority>1</filterpriority>

   23     public IEnumerator<T> GetEnumerator()

   24     {

   25         return underlyingList.GetEnumerator();

   26     }

   27 

   28     /// <summary>

   29     /// Returns an enumerator that iterates through a collection.

   30     /// </summary>

   31     /// <returns>

   32     /// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.

   33     /// </returns>

   34     /// <filterpriority>2</filterpriority>

   35     IEnumerator IEnumerable.GetEnumerator()

   36     {

   37         return underlyingList.GetEnumerator();

   38     }

   39 

   40     #endregion

   41 

   42     #region Implementation of IEnumerableList<T>

   43 

   44     /// <summary>

   45     /// Gets the <see cref="T"/> at the specified index.

   46     /// </summary>

   47     /// <value></value>

   48     public T this[int index]

   49     {

   50         get { return underlyingList[index]; }

   51     }

   52 

   53     /// <summary>

   54     /// Gets the count.

   55     /// </summary>

   56     /// <value>The count.</value>

   57     public int Count

   58     {

   59         get { return underlyingList.Count; }

   60     }

   61 

   62     #endregion

   63 }

And the final solution looks like the following:

    1 public class Item

    2    {

    3        public IEnumerableList<Bid> Bids

    4        {

    5            get

    6            {

    7                return new EnumerableList<Bid>(_bids);

    8            }

    9        }

   10        private IList<Bid> _bids;

   11 

   12        public Item()

   13        {

   14            _bids = new List<Bid>();

   15        }

   16 

   17        public void AddBid(Bid bid)

   18        {

   19            _bids.Add(bid);

   20        }

   21    }

   22 

   23    public class Bid

   24    {

   25    }

In this case the domain model doesn’t allow me to do prohibited action.

Original article was published at www.Catarsa.com

Advertisements