I’m working on an app where I need to call one of two data methods based on the generic type of the calling class. For example, if T is of type Foo, I’ll call data.GetFoo():
private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
using (MesReportingDal data = new MesReportingDal())
{
return data.GetFoo(mostRecentProcessedReadTime); // Notice GetFoo()
}
}
And if T is of type Bar, I’ll call data.GetBar():
private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
using (MesReportingDal data = new MesReportingDal())
{
return data.GetBar(mostRecentProcessedReadTime); // Notice GetBar()
}
}
Before now, I only needed one DAL method because all types were retrieved the same way. I now need to call one of two methods, depending on the type of T.
I’m trying to avoid something like this:
private static List<T> GetObjectList(DateTime mostRecentProcessedReadTime)
{
using (MesReportingDal data = new MesReportingDal())
{
if (T is Foo) { return data.GetFoo(mostRecentProcessedReadTime); }
if (T is Bar) { return data.GetBar(mostRecentProcessedReadTime); }
}
}
This violates OCP. Is there an elegant way to handle this, so I can get rid of my if statement?
Edit – This is what the types look like
public partial class Foo1 : IDataEntity { }
public partial class Foo2 : IDataEntity { }
public partial class Bar1 : IDataEntity { }
public partial class Bar2 : IDataEntity { }
These Foos and Bars are the DBML items used with Linq-to-SQL.
I would change
GetFooandGetBarto just beGet, and makeMesReportingDala generic too.So I think you would end up with something like this:
Incidentally, having the
usingstatement also requires that theMesReportingDalimplementsIDisposable, otherwise you’ll get the following compile error:‘MesReportingDal’: type used in a using statement must be implicitly convertible to ‘System.IDisposable’
UPDATE
So after thinking about this some more and reading your feedback, one option you have is to extract a repository interface and push the creation back to a factory method. This will allow you to maintain the single
data.Get(...)call, but with different implementations based onTYour factory could then look something like this
And this would allow you to keep your initial code block clean
Hope that helps.