Reputation: 423
I try to implement factory pattern with interface for create different type of Response, but I don't know if I'm doing it right. When I call my method SetExceptionResponse
with factory class, I must to cast it.
Interface :
public interface IResponse
{
int ErrorCode { get; set; }
HeaderResponse HeaderResponse { get; set; }
IResponse SetExceptionResponse(int code, string title, string[] errors);
}
Main class :
public class Response : IResponse
{
public int ErrorCode { get ; set ; }
public HeaderResponse HeaderResponse { get; set; } = null;
public virtual IResponse SetExceptionResponse(int code, string title, string[] errors)
{
HeaderResponse headerResponse = new HeaderResponse();
if (errors.Length > 0)
{
foreach (string item in errors)
headerResponse.ErrorList.Add(item);
}
headerResponse.Title = title;
headerResponse.StatusCode = code;
return new Response
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
}
Other class who herits main class:
public class DeleteShipmentResponse : Response
{
public string Value { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
public override IResponse SetExceptionResponse(int code, string title, string[] errors)
{
HeaderResponse headerResponse = new HeaderResponse();
if (errors.Length > 0)
{
foreach (string item in errors)
headerResponse.ErrorList.Add(item);
}
headerResponse.Title = title;
headerResponse.StatusCode = code;
return new DeleteShipmentResponse
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
My factory class :
public static class ResponseFactory
{
public static IResponse CreateResponse()
{
return new Response();
}
public static IResponse CreateDeleteResponse()
{
return new DeleteShipmentResponse();
}
public static IResponse CreateShipmentResponse()
{
return new ShipmentResponse();
}
public static T CreateResponse<T>()
where T : IResponse
{
return (T)CreateResponse(typeof(T));
}
public static IResponse CreateResponse(Type type)
{
if (type == typeof(Response))
return CreateResponse();
if (type == typeof(DeleteShipmentResponse))
return CreateDeleteResponse();
else if (type == typeof(ShipmentResponse))
return CreateShipmentResponse();
else
throw new ArgumentOutOfRangeException(string.Format(CultureInfo.InvariantCulture, "Unrecognized type [{0}]", type.FullName), "type");
}
}
So, when I use factory to create DeleteShipmentResponse and call SetExeceptionResponse I do this :
DeleteShipmentResponse result = (DeleteShipmentResponse)ResponseFactory.CreateResponse<DeleteShipmentResponse>().SetExceptionResponse(500, "Exception in DeleteShipment()", new string[] { ex.Message });
I must cast with DeleteShipmentResponse otherwise cast exception throw.
How do I get this without typecasting to DeleteShipmentResponse ? Do I have to use generic interface ?
Thanks for help
Upvotes: 1
Views: 580
Reputation: 141825
If it is ok for all IResponse
's to have a parameterless constructor, you can make IResponse
generic "of itself", i.e. with T
constrained to IResponse<T>
:
public interface IResponse<T> where T : IResponse<T>
{
int ErrorCode { get; set; }
HeaderResponse HeaderResponse { get; set; }
T SetExceptionResponse(int code, string title, string[] errors);
}
public class Response<T> : IResponse<T> where T : IResponse<T>, new
{
public int ErrorCode { get; set; }
public HeaderResponse HeaderResponse { get; set; } = null;
public virtual T SetExceptionResponse(int code, string title, string[] errors)
{
HeaderResponse headerResponse = new HeaderResponse();
.....
return new T
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
}
public class DeleteShipmentResponse : Response<DeleteShipmentResponse>
{
...
public override DeleteShipmentResponse SetExceptionResponse(int code, string title, string[] errors)
{
....
return new DeleteShipmentResponse
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
}
Upvotes: 3