0

I have a class, it needs to process data differently based on user input.

There are two processor classes which both adhere to the same interface but behave slightly differently.

My IOC container is injecting an IThingerFactory to my Program instance.

An example with my current solution can be seen below.

Is there a better way to solve this problem?

public class Program
{
    public IThingerFactory ThingerFactory { get; set; }

    public Program(IThingerFactory thingerFactory)
    {
        ThingerFactory = thingerFactory;
    }

    public void FunctionWhichDoesStuff(int? input)
    {
        ThingerFactory.GetThinger(input).DoAThing();
    }
}

public interface IThinger
{
    void DoAThing();
}

public class DailyThinger : IThinger
{
    public void DoAThing()
    {
        throw new NotImplementedException();
    }
}

public class MonthlyThinger : IThinger
{
    public MonthlyThinger(int monthNumber)
    {
        MonthNumber = monthNumber;
    }

    public int MonthNumber { get; set; }

    public void DoAThing()
    {
        throw new NotImplementedException();
    }
}

public interface IThingerFactory
{
    IThinger GetThinger(int? number);
}

public class ThingerFactory : IThingerFactory
{
    public IThinger GetThinger(int? number)
    {
        return number.HasValue ?
            new MonthlyThinger(number.Value) as IThinger : 
            new DailyThinger() as IThinger;
    }
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
english fool
  • 105
  • 5
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Mar 27 '15 at 16:05
  • Mmm, hard to know exactly what you are doing because "Thinger" is vague... But the fact that `MonthlyThinger` exposes a public property `MonthNumber` but obviously `DailyThinger` doesn't suggests maybe you are mixing your concerns and might want to break `IThinger` interface out a bit so that monthly inherits two interfaces and daily just one? That might fix your factory too and keep everything consistent? – Belogix Mar 27 '15 at 16:07
  • Related: http://stackoverflow.com/a/1945023/126014 – Mark Seemann Mar 27 '15 at 16:27
  • It sounds like a classic case of having to select a Service based on a run-time value. See these three articles for three alternative ways of approaching this problem: http://blog.ploeh.dk/2013/01/09/MetadataRoleHint http://blog.ploeh.dk/2013/01/10/RoleInterfaceRoleHint http://blog.ploeh.dk/2013/01/11/PartialTypeNameRoleHint See also section 6.1 *Mapping runtime values to Abstractions* in [my book](http://amzn.to/12p90MG). – Mark Seemann Mar 27 '15 at 16:31

1 Answers1

1

Since you emphasize the use of IOC I guess your real question is if the IOC could do the work. I think that the IOC should only be used at start-up to make a static object graph and that the Factory pattern (or other patterns) should be used later on. So you code looks fine to me.

Ruben Bartelink
  • 59,778
  • 26
  • 187
  • 249
Stig
  • 1,974
  • 2
  • 23
  • 50