I'm thinking of the options in regards to implementing a single unit of work for dealing with multiple datasources - Entity framework. I came up with a tentative approach - for now dealing with a single context - but it apparently isn't a good idea.
If we were to analyze the code below, would you consider it a bad implementation? Is the lifetime of the transaction scope a potential problem?
Of course if we wrap the transaction scope with different contexts we'd be covered if the second context.SaveChanges() failed...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
using(UnitOfWork unitOfWork = new UnitOfWork())
{
var repository = new EmployeeRepository(unitOfWork);
var employee = repository.CreateOrGetEmployee("Whatever Name");
Console.Write(employee.Id);
unitOfWork.SaveChanges();
}
}
}
class UnitOfWork : IDisposable
{
TestEntities _context;
TransactionScope _scope;
public UnitOfWork()
{
_scope = new TransactionScope();
_context = new TestEntities();
}
public void SaveChanges()
{
_context.SaveChanges();
_scope.Complete();
}
public TestEntities Context
{
get
{
return _context;
}
}
public void Dispose()
{
_scope.Dispose();
_context.Dispose();
}
}
class EmployeeRepository
{
UnitOfWork _unitOfWork;
public EmployeeRepository(UnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public Employee GetEmployeeById(int employeeId)
{
return _unitOfWork.Context.Employees.SingleOrDefault(e => e.Id == employeeId);
}
public Employee CreateEmployee(string fullName)
{
Employee employee = new Employee();
employee.FullName = fullName;
_unitOfWork.Context.SaveChanges();
return employee;
}
public Employee CreateOrGetEmployee(string fullName)
{
var employee = _unitOfWork.Context.Employees.FirstOrDefault(e => e.FullName == fullName);
if (employee == null)
{
employee = new Employee();
employee.FullName = fullName;
this.AddEmployee(employee);
}
return employee;
}
public Employee AddEmployee(Employee employee)
{
_unitOfWork.Context.Employees.AddObject(employee);
_unitOfWork.Context.SaveChanges();
return employee;
}
}
}