views:

282

answers:

1

I'm experimenting with IoC on my way to TDD by fiddling with an existing project. In a nutshell, my question is this: what are the best practices around IoC when public and non-public methods are of interest?

There are two classes:

public abstract class ThisThingBase
{
    public virtual void Method1() {}
    public virtual void Method2() {}

    public ThatThing GetThat()
    {
        return new ThatThing(this);
    }
    internal virtual void Method3() {}
    internal virtual void Method4() {}
}

public class Thathing
{
    public ThatThing(ThisThingBase thing)
    {
        m_thing = thing;
    }
    ...
}

ThatThing does some stuff using its ThisThingBase reference to call methods that are often overloaded by descendents of ThisThingBase.

Method1 and Method2 are public. Method3 and Method4 are internal and only used by ThatThings.

I would like to test ThatThing without ThisThing and vice-versa.

Studying up on IoC my first thought was that I should define an IThing interface, implement it by ThisThingBase and pass it to the ThatThing constructor. IThing would be the public interface clients could call but it doesn't include Method3 or Method4 that ThatThing also needs.

Should I define a 2nd interface - IThingInternal maybe - for those two methods and pass BOTH interfaces to ThatThing?

A: 

The problem with IoC containers is when they can't control the lifecycle of the objects. Why the factory method on ThisThingBase? If it would be possible to have the IoC container construct Thatthing it would increase testability.

It's hard to say based on the example but it's possible you have unnecessary coupling between Thatthing and ThisThingBase.

Interfaces can be good but sometimes it's enough with virtual methods on the class you depend upon to enable testing.

Cristian Libardo
Excellent point about the ThatThing factory - there is one, actually, but I was worried my post was getting too long as it was. Maybe I shouldn't have made up the whole thisthing/thathing thing. The project is for Amateur radio and interfacing to physical devices. I thought that was too much.
n8wrl
The problem is that these things are very hard to discuss in the abstract, because there are a lot of options, and which ones make sense depends on the details. So I would encourage you to actually base your question on your real code.
Ilja Preuß