Reputation: 531
I have a controller that has 3 methods with the same method body. The only difference is the method type. I have a generic type interface that I'm injecting into the controller. I'm injecting the interface because I'm using an IoC (StructureMap).
The problem is that the return type of the controller methods doesn't match the generic type of the method in my interface. (GetStatistics1
and GetStatistics2
)
For demonstration purposes, I changed the 3rd method (GetStatistics3
). I have casted the return type from IEnumerable<T>
to IEnumerable<Type3>
. The code compiles, but I'm not sure if that is the most efficient or eloquent solution.
The code is below:
Interface:
public interface IStatistics<T>
{
IEnumerable<T> ExecStatistics_SP(DateTime ? date,
int ? xd, string iap, int? statisticsType );
}
Controller:
public class StatisticsController : ApiController
{
private readonly IStatistics<T> _repo;
public StatisticsController(IStatistics<T> repo)
{
_repo = repo;
}
public IEnumerable<Type1> GetStatistics1(string iap, DateTime date, int? statisticsType, int xd)
{
return _repo.ExecStatistics_SP(date,xd,iap,statisticsType).AsEnumerable();
}
public IEnumerable<Type2> GetStatistics2(string aip, DateTime date, int? statisticsType, int xd)
{
return = _repo.ExecStatistics_SP(date, xd, iap, statisticsType).AsEnumerable();
}
public IEnumerable<Type3> GetStatistics3(string iap, DateTime date, int? statisticsType, int xd)
{
returnValue = _repo.ExecStatistics_SP(date,xd,iap,statisticsType).AsEnumerable();
return (IEnumerable<Type3>) returnValue;
}
}
Upvotes: 1
Views: 1637
Reputation: 5369
TL;DR I doubt this is possible in Web API; you're probably best off creating separate controllers for different classes.
The problem with the code itself lies in the class definition. StatisticsController
doesn't know what T
is, meaning the compiler cannot check that ExecStatistics_SP
returns a compatible type.
Furthermore, since IStatistics<T>
is injected into the class, there is no way to differentiate between what T
is within each method unless you reflect over T
each call.
Another way to approach this is to let the language handle everything and simplify your class in the process. With this solution, the caller of StatisticsController
knows what T
is, in your example it is either Type1
, Type2
, or Type3
. In reality, T
can be any class implementing IStatistics<T>
.
public class StatisticsController<T>
{
private readonly IStatistics<T> _repo;
public StatisticsController(IStatistics<T> repo)
{
_repo = repo;
}
public IEnumerable<T> GetStatistics(string iap, DateTime date, int? statisticsType, int xd)
{
return _repo.ExecStatistics_SP(date, xd, iap, statisticsType);
}
}
I'm not sure how your DI framework handles this in the context of Web API, but whoever calls GetStatistics
must have already instantiated StatisticsController
with a type implementing IStatistics<T>
. Usage in your own code would look like the following:
var repo = new StatisticsRepo<Type1>(); // Made-up repo class
var controller = new StatisticsController<Type1>(repo);
IEnumerable<Type1> values = controller.GetStatistics(...);
// etc
Upvotes: 1