tags:

views:

142

answers:

2

Hi,

I have two repository classes below, MoneyTransferRepository class is used by other classes in my project. I have designed it this way - is it right? If not, what is the best way?

Thanks

public interface IMoneyTransferRepository
{
    void UpdateBalance();
}

public interface IOrderRepository
{
    void Checkout();
    void SaveOrder();
}

public class MoneyTransferRepository : IMoneyTransferRepository
{
    DBDataContext DB;

    public MoneyTransferRepository(IDbConnection connection)
    {
        DB = new DBDataContext(connection);
    }

    public void UpdateBalance()
    {
        //do something DB.Table1.Update
    }

}


public class OrderRepository : IOrderRepository,IMoneyTransferRepository
{

    DBDataContext DB;
    IMoneyTransferRepository moneyTransferRepository;

    public OrderRepository()
    {
        DB = new DBDataContext();
        moneyTransferRepository = new MoneyTransferRepository(DB.Connection);
    }

    public void Checkout()
    {
        TransactionOptions transactionOptions = new TransactionOptions();
        transactionOptions.IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted;

        using (TransactionScope transactionScope = new TransactionScope(TransactionScopeOption.Required, transactionOptions))
        {
            try
            {
                UpdateBalance();
                SaveOrder();
                transactionScope.Complete();
            }
            catch
            {

            }

        }
    }

    public void UpdateBalance()
    {
        moneyTransferRepository.UpdateBalance();
    }

    public void SaveOrder()
    {
        //do something DB.SaveOrder.Update ......
        //   DB.Updatestock .....

    }
}
+1  A: 

This is most definitely not the correct usage of the repository pattern. I find the easiest way to think about the repository is to imagine every Order in your system is available in a big collection (the repository). That said you probably want to add a way to query for specific objects from the repository (either via a Query pattern or direct method calls).

In our system we would have a service layer method called Checkout that would look like this...

    public void Checkout(int customerId)
    {
        if(CustomerHasOpenOrder(customerId) == false)
        { 
           // do something depending on your standards.  For us we'd 
           // throw an exception
        }

        Order orderToCheckout = m_OrderRepository.FindOpenOrderForCustomer(customerId);

        orderToCheckout.Checkout();

        m_OrderRepository.Save(orderToCheckout);
    }

In our system we don't actually use int's for identifying Orders but you get the idea...

ShaneC
+2  A: 

Don't do transaction management in Repository. Thats why you get confused.

More info is here: http://stackoverflow.com/questions/575136/transactions-in-the-repository-pattern

ercu