0

I want to inject a type IGameScoreSource into a class but I'm stumped how to go about it.

static class GamesScoreSourceFactory
{
    public IGameScoreSource GetGameScoreSource(GameScoreSourceType gameScoreSourceType)
    {
        switch(gameScoreSourceType)
        {
            case FromFile:
                return new GameScoreFile();
            case FromDB:
                return new DatabaseRepos();
            case FromThirdPartyAPI:
                return new ThirdPartyWrapper();
        }   
    }
}

I have two questions for two different scenarios.

All three cases magically figure out where to source the parameters. So for GameScoreFile it knows what file path to look at, for DatabaseRepos it knows where to find the connection string.

Presumably, these locations are hard-coded in the concrete classes. But what if I wanted to change the locations? Assuming scores.txt was hard coded in GameScoreFile.cs what if instead I wanted rand_scores.txt?

So:

 static class GamesScoreSourceFactory
    {
        public IGameScoreSource GetGameScoreSource(GameScoreSourceType gameScoreSourceType, string param)
        {
            switch(gameScoreSourceType)
            {
                case FromFile:
                    return new GameScoreFile(string param);
                case FromDB:
                    return new DatabaseRepos(string param);
                case FromThirdPartyAPI:
                    return new ThirdPartyWrapper(ThirdPartyConfig conf{IPAddress = ipAddress, Port = port});
            }   
        }
    }

The first two cases were fine but the third case doesn't because it takes a config object.

Do I have to create another factory class? But won't the calling code have to know which Factory object to invoke, and as result becomes a Factory in itself?

I'm not sure how to handle this... If this is a duplicate please link me.

Lews Therin
  • 10,907
  • 4
  • 48
  • 72
  • You could have a IGameScoreSourceConfig interface implemented by GameScoreConfig/DatabaseRepoConfig/ThirdPartyConfig and inject it into the factory. Then in the right switch statement just convert it into actual object. Think something like adapter patter. – peeyush singh Mar 01 '19 at 06:30
  • Check this out: https://stackoverflow.com/questions/31950362/factory-method-with-di-and-ioc. The way to go is strategy pattern – MistyK Mar 01 '19 at 08:25
  • @peeyushsingh But how do you decide which config interface to inject? That would require another factory and a duplicate check. What I want to avoid – Lews Therin Mar 03 '19 at 22:54
  • @MistyK Looks interesting, will check it out – Lews Therin Mar 03 '19 at 22:54

2 Answers2

0

You would ideally inject below types as dependency to factory class

GameScoreFile
DatabaseRepos
ThirdPartyWrapper

That way, whichever framework you use for dependency resolution knows what to pass for corresponding type.

Sateesh Pagolu
  • 9,282
  • 2
  • 30
  • 48
0

I'd try to isolate the dependencies such that the factory class does not have to know too much.

Let's say that each of your concrete implementations of IGameScoreSource has its own dependencies. In the example above, two needed a string and the third needed a ThirdPartyConfig.

This does not look like much but as you go along and refactor your classes, every time you introduce or change a dependency, the factory class has to change as well. Not ideal.

You could make a factory for each of the concrete types, and then any change to one of the implementation would only affect its own factory. The main factory class would then only work with these specific factories and not be affected on each change.

The right solution depends on your domain model and the IOC approach you are using.

Tomas Kohl
  • 1,388
  • 1
  • 19
  • 27