Search code examples
c#genericspolymorphismfactory-pattern

Abstract factory pattern instead of generics - how?


I have a generic interface:

public interface IReader<T> where T: Result
{
   IEnumerable<T> ReadResults();
}

where Result is a base class and is extended into DetailedResult:

public class Result
{
    // ...
}

public class DetailedResult : Result
{
    // ... ...
}

Now I have two concrete types for IReader, each of this implementation returns different type, specific to the reader type:

public class DefaultResultReader<Result> : IReader<Result>
{
    IEnumerable<Result> ReadResults();
}

and

public class DetailedResultReader<DetailedResult> : IReader<DetailedResult>
{
    IEnumerable<DetailedResult> ReadResults();
}

The structure presented above uses generics. I would like to get rid of it if possible, and have some kind of a factory which would create a concrete implementation of IReader for me - DefaultResultReader.ReadResults() method must return Result while DetailedResultReader.ReadResults() must return DetailedResult

My question is how should the abstract factory look for this structure - how to design it so that I can create specific IReader object as requested ?


Solution

  • i didn't get exactly what you want, but i guess you expect something the following :

    public interface IReader<T> where T : Result
    {
        IEnumerable<T> ReadResults();
    }
    
    public class Result
    {
    }
    
    public class DetailedResult : Result
    {
        // ... ...
    }
    
    public class DefaultResultReader : IReader<Result>
    {
        public IEnumerable<Result> ReadResults()
        {
            return null;
        }
    }
    
    public class DetailedResultReader : IReader<DetailedResult>
    {
        public IEnumerable<DetailedResult> ReadResults()
        {
            return null;
        }
    }
    
    public abstract class ResultReaderAbsractFactory
    {
        public abstract IReader<Result> CreareDefaultResultReader();
        public abstract IReader<DetailedResult> CreareDetailedResultReader();
    }
    
    public class ConcreteResultRaderFactory : ResultReaderAbsractFactory
    {
        public override IReader<Result> CreareDefaultResultReader()
        {
            return new DefaultResultReader();
        }
    
        public override IReader<DetailedResult> CreareDetailedResultReader()
        {
            return new DetailedResultReader();
        }
    }