maniac
maniac

Reputation: 159

Factory pattern return generic types in c#

public interface IRequestProcessor<out T>
{    
   T Translate(string caseId);
}

public class xyzReqProcessor : IRequestProcessor<xyzType>
{
  public xyzType Process(string xyzMsg)
  {
     return new xyz();
  }
}
public class VHDReqProcessor : IRequestProcessor<VHDType>
{
  public VHDType Process(string xyzMsg)
  {
     return new VHD();
  }
}

till here it looks good. now i want to initialize the class with factory but it's not able to return IRequestProcessor type of object.

public static IRequestProcessor Get(FormType translatorType)
{

  IRequestProcessor retValue = null;
  switch (translatorType)
  {
    case EFormType.VHD:
      retValue = new VHDProcessor();
      break;
    case EFormType.XYZ: 
      retValue = new XYZProcessor();
      break;
  }
  if (retValue == null)
    throw new Exception("No Request processor found");

  return retValue;

}

at the time of calling Factory.Get(FormType translatorType) method I dont want to specify any fixed object type like below

Factory.Get< XYZType>(FormType translatorType)

Upvotes: 5

Views: 4745

Answers (1)

Johnny
Johnny

Reputation: 9519

I am not sure if this solution fits into your overall design but with this trick you can achieve what you have asked for. The point is to have two interfaces, one generic and one not where the not generic interface route calls to generic one. See bellow:

public abstract class BaseType
{
    public abstract void Execute();
}

public class VhdType : BaseType
{
    public override void Execute()
    {
        Console.WriteLine("Vhd");
    }
}

public class XyzType : BaseType
{
    public override void Execute()
    {
        Console.WriteLine("Xyz");
    }
}

public interface IRequestProcessor
{
    BaseType Process();
}

public interface IRequestProcessor<T> : IRequestProcessor where T : BaseType, new()
{
    T Process<TInput>() where TInput : T;
}

public class VhdRequestProcessor : IRequestProcessor<VhdType>
{
    public BaseType Process()
    {
        return Process<VhdType>();
    }

    public VhdType Process<TInput>() where TInput : VhdType
    {
        return new VhdType();
    }
}

public class XyzRequestProcessor : IRequestProcessor<XyzType>
{
    public BaseType Process()
    {
        return Process<XyzType>();
    }

    public XyzType Process<TInput>() where TInput : XyzType
    {
        return new XyzType();
    }
}

public class RequestFactory
{
    public IRequestProcessor GetRequest(string requestType)
    {
        switch (requestType)
        {
            case "vhd": return new VhdRequestProcessor();
            case "xyz": return new XyzRequestProcessor();
        }

        throw new Exception("Invalid request");
    }            
}

Usage example:

IRequestProcessor req = new RequestFactory().GetRequest("xyz");
BaseType r = req.Process();
r.Execute();

Upvotes: 4

Related Questions