2

I have this ctor:

    public Section()
    {
        _tabs = new TabCollection(this);
        _sections = new SubSectionCollection(this);
    }

I would like to get something like this:

public Section()
        : this(new TabCollection(this), new SubSectionCollection(this))
    {

    }

     public Section(TabCollection tabCollection, IList<ISection> sections)
     {
         _tabs = tabCollection;
         _sections = sections;

     }

Of course this doesn't work. Anyone has any suggestion how I could refactor this code? I need to do this in order to be able to Mock an object of type Section in Unit Testing. We are using FakeItEasy testing framework.

IonutC
  • 607
  • 1
  • 6
  • 11
  • 1
    You have duplicate code in your second example - you don't need the content lines in the first constructor. Other than that, it's not a completely dependency-injected solution, but I don't see why the code would fail. – Dan Puzey Oct 23 '12 at 15:30
  • Yes, my bad, I don't use the content lines in the first ctor. I was in a hurry when I copy paste it. So the first ctor does not contain anything. I need a default constructor in order to be able to fake an object of type Section for unit testing. – IonutC Oct 23 '12 at 19:10

2 Answers2

1

One issue is that your first constructor, the one with no parameters, delegates to the second constructor. In other words, the second one will be invoked by the first one with the parameters in the this() statement. Yet, the first one also contains setters for _tabs and _sections, which is redundant. It should look like this:

public Section()
    : this(new TabCollection(this), new SubSectionCollection(this))
{ }

public Section(TabCollection tabCollection, IList<ISection> sections)
{
    _tabs = tabCollection;
    _sections = sections;
}

This is constructor chaining, though, which is a technique used in dependency injection. Is this what you're asking about?

neontapir
  • 4,698
  • 3
  • 37
  • 52
  • Yes, you are right. I need to use this chaining and dependency injection in order to be able to fake an object of type Section. I know I should use interfaces for tabcollection and SubSectionCollection, but this is not the point. The problem is, because I have the word "this" when instantiating TabCollection and SubSectionCollection I cannot do the chaining. – IonutC Oct 23 '12 at 19:13
1

Dependency injection doesn't necessarily mean your class can't instantiate some of it's fields/properties upon construction. I typically use constructor injection for "services", not a collection of children objects.

However, I don't know all the specifics of your code, so you might want to use the Factory pattern. Something like a SectionFactory might make sense here...

public class Section
{
    internal Section(TabCollection tabColl, SectionCollection subSections)
    {
        // check for null, etc.

        // do whatever you need to do to finish construction
        tabColl.Parent = this;
        subSections.Parent = this;
    }
}

public class SectionFactory : ISectionFactory
{
    public Section Create()
    {
        var tabs = new TabCollection();
        var subs = new SectionCollection();

        return new Section(tabs, subs);
    }
}
BlakeH
  • 3,354
  • 2
  • 21
  • 31