I'm struggling with the design of a method CallSystemX()
that needs to accept a parameter of multiple Type
s. To get around it I created an interface called IRequest
to be able to pass different types of objects into my method, but that introduced new problems since I have a builder that needs to know the 'real' underlying type to be able to do its job.
Here is a contrived example:
public interface IRequest
{
string Key { get; set; }
string[] Names();
}
class User : IRequest
{
public string id { get; set; }
public string Key { get; set; }
public string[] Names() { return new string[] { "a", "b", "c" }; }
//...
}
class Company : IRequest
{
public string Adress { get; set; }
public string Key { get; set; }
public string[] Names() { return new string[] { "a", "b", "c" }; }
//...
}
/// <summary>
/// This method will be called from MANY places throughout the application
/// </summary>
public List<T> CallSystemX(IRequest request) where T : class
{
log.Debug($"processing request {request.Key}");
// Alternative 1. Static object with code for building output.
// Problem: BuildOutputForSystemX() does not know the underlying type
var output = StaticBuilder.BuildOutputForSystemX(request, otherData, otherData2);
// Alternative 2. IRequest offers a method.
// Problem: Why should 'Company' or 'User' have code related to some other system,
// thus unrelated to its own class
var output = request.BuildOutputForSystemX(otherData, otherData2);
// Alternative 3. Injection
// feels weird. The injected object still does not know the underlying type of 'request'
// but still better the alternative 2.
var output = request.BuildOutputForSystemX(StaticBuilder, otherData, otherData2);
return CallLowLevelFunc(output);
}
Goals:
- I would like to avoid duplicating
CallSystemX()
for each type - The Builder can not work with
IRequest
objects. It needs to work with the 'real' datatype. In this example:User
andCompany
- It is ok to change the signature of
CallSystemX
. Perhaps add/change/remove parameters - If at all possible avoid reflection
I looked at a proxy-pattern but I am not sure how that would solve my problem.
CallSystemX()
as a string.