Tuesday, November 30, 2010

Entity framework creating a Generic Repository and UnitOfWork implementation – Part 2

We have now moved our validation and base entity property change logic to the base repository implementation. So we can now remove the SavingChanges event code from the ObjectContext implementation. The changed code looks like
public class ShoppingCartContext : ObjectContext
{
    public ShoppingCartContext() : base("name=ShoppingCartModelContainer", "ShoppingCartModelContainer") { }

    public override int SaveChanges(SaveOptions options)
    {
        this.DetectChanges();
        return base.SaveChanges(options & ~SaveOptions.DetectChangesBeforeSave);
    }

    public ObjectSet<Customer> Customers
    {
        get { return _customers ?? CreateObjectSet<Customer>(); }
    }

    public ObjectSet<Order> Orders
    {
        get { return _orders ?? CreateObjectSet<Order>(); }
    }

    public ObjectSet<Product> Products
    {
        get { return _products ?? CreateObjectSet<Product>(); }
    }      

    ObjectSet<Customer> _customers;
    ObjectSet<Order> _orders;
    ObjectSet<Product> _products;
}

Once the base repository is ready, we can now create repositories for our entities in the model. I’ll show the code for the customer repository implementation.
public interface ICustomerRepository : IRepository<Customer>
{
    EF4Recipies.Models.Customer GetByEmail(string email);
    System.Collections.Generic.IEnumerableCustomer> SearchByName(string name);
}

public class CustomerRepository : BaseRepository<Customer>, ICustomerRepository
{
    public CustomerRepository(IUnitOfWork unitOfWork) : base(unitOfWork) { }

    public override IEnumerable<Customer> All()
    {
        return Context.Customers;
    }

    public override void Remove(Customer entity)
    {
        Context.Customers.Attach(entity);
        base.Remove(entity);
    }

    public override void Update(Customer entity)
    {
        Context.Customers.Attach(entity);
        base.Update(entity);
    }

    public Customer GetByEmail(string email)
    {
        return base.GetOneByCondition(customer => customer.Email == email);
    }

    public IEnumerable<Customer> SearchByName(string name)
    {
        return base.AllByCondition(customer => string.Concat(customer.FirstName, customer.LastName).Contains(name));
    }
}

Test cases:
[TestMethod()]
public void All_should_return_the_complete_set_of_customers_in_db()
{
    IUnitOfWork unitOfWork = UnitOfWork.Default;
    CustomerRepository target = new CustomerRepository(unitOfWork); 
           
    var customers = target.All();
    Assert.IsTrue(customers.Count() > 0);
}

[TestMethod()]
public void GetByEmail_should_return_customer_with_email_address_passed()
{
    IUnitOfWork unitOfWork = UnitOfWork.Default;
    CustomerRepository target = new CustomerRepository(unitOfWork);
    string email = "prajeesh.prathap@gmail.com";
    var customer = target.GetByEmail(email);
    Assert.AreEqual<string>(email, customer.Email);
}

[TestMethod]
public void Add_method_should_add_customer_to_the_context()
{
    IUnitOfWork unitOfWork = UnitOfWork.Default;
    CustomerRepository target = new CustomerRepository(unitOfWork);
    Customer customer = new Customer
    {
        FirstName = "SampleFName",
        LastName = "SampleLName",
        Email = "ValidEmail@gmail.com"               
    };

    target.Add(customer);
    unitOfWork.Save();

    unitOfWork = UnitOfWork.Default;
    CustomerRepository newRepository = new CustomerRepository(unitOfWork);
    var newCustomer = newRepository.GetByEmail("ValidEmail@gmail.com");
    Assert.IsNotNull(newCustomer);
    unitOfWork.ExecuteCommandOnDb("delete from [dbo].[Customers] where Id = '" + newCustomer.Id.ToString() + "'");           
}


No comments: