Consider these methods: public List<Employee> GetAllEmployees() { using (Entitie
ID: 642855 • Letter: C
Question
Consider these methods:
public List<Employee> GetAllEmployees()
{
using (Entities entities = new Entities())
{
return entities.Employees.ToList();
}
}
public List<Job> GetAllJobs()
{
using (Entities entities = new Entities())
{
return entities.Jobs.ToList();
}
}
public List<Task> GetAllTasksOfTheJob(Job job)
{
using (Entities entities = new Entities())
{
return entities.Tasks.Where(t => t.JobId == job.Id).ToList();
}
}
Using block is the same and has been repeated 3 times here (of course, more than 100 times in the real application). How is it possible to implement DRY (Don't Repeat Yourself) principal for using block? Is it considered a breach of DRY principal at all?
Update: I'm not talking about what has been implemented inside the using block. What I actually mean here, is the using (Entities entities = new Entities()). This line is repeated 100 times or more.
Explanation / Answer
One idea would be to wrap it with a function that takes a Func.
Something like this
public K UsingT<T,K>(Func<T,K> f) where T:IDisposable,new()
{
using (T t = new T())
{
return f(t);
}
}
Then your above code becomes
public List<Employee> GetAllEmployees()
{
return UsingT<Entities,List<Employee>>(e=>e.Employees.ToList());
}
public List<Job> GetAllJobs()
{
return UsingT<Entities,List<Job>>(e=>e.Jobs.ToList());
}
public List<Task> GetAllTasksOfTheJob(Job job)
{
return UsingT<Entities,List<Task>>(e=>e.Tasks.Where(t => t.JobId == job.Id).ToList());
}
I made Entities a type param too, because I'm assuming you have more than one type you're doing this with. If you're not, you could remove it and just use the type param for the return type.
To be honest though this sort of code doesn't help readability at all. In my experience the more Jr co-workers have a really tough time with it as well.
Update Some additional variations on helpers you might consider
//forget the Entities type param
public T UsingEntities<T>(Func<Entities,T> f)
{
using (Entities e = new Entities())
{
return f(e);
}
}
//forget the Entities type param, and return an IList
public IList<T> ListFromEntities<T>(Func<Entities,IEnumerable<T>> f)
{
using (Entities e = new Entities())
{
return f(e).ToList();
}
}
//doing the .ToList() forces the results to enumerate before `e` gets disposed.