I am currently using iBATIS.NET for a small application I am building. I like to create concrete Classes for my DAOs instead of using ISqlMapper directly and invoking named SQL statements. I am not using a Dependency Injection container of any sort, so ideally I have my DAOs set up as follows:
public abstract class AbstractDAO
{
/// <summary>
/// SQL Mapper.
/// </summary>
ISqlMapper mapper;
/// <summary>
/// Default Constructor.
/// </summary>
/// <param name="mapper"></param>
public AbstractDAO(ISqlMapper mapper)
{
this.mapper = mapper;
}
}
public class NodeDAO : AbstractDAO
{
/// <summary>
/// Default Constructor.
/// </summary>
/// <param name="mapper"></param>
public NodeDAO(ISqlMapper mapper) : base(mapper) { }
/// <summary>
/// Insert Node.
/// </summary>
/// <param name="node"></param>
public void InsertNode(Node node)
{
// ... Assume Some Pretty Code.
}
}
public class NodeRevisionDAO : AbstractDAO
{
/// <summary>
/// Default Constructor.
/// </summary>
/// <param name="mapper"></param>
public NodeRevisionDAO (ISqlMapper mapper) : base(mapper) { }
/// <summary>
/// Insert Node Revision.
/// </summary>
/// <param name="nodeRevision"></param>
public void InsertNodeRevision(NodeRevision nodeRevision)
{
// ... Assume Some Pretty Code.
}
}
From my main application code, let's say in some form of Business Layer, I would ideally call two insert Methods on the DAOs:
// ... Assume DAOs are Initialized.
nodeDAO.InsertNode(node);
nodeRevisionDAO.InsertNodeRevision(nodeRevision);
I want to make sure both statements are executed as an atomic operation in a transaction so that if either fails, both will be rolled back. But because the ISqlMapper is injected in both DAOs I have no control over the transactions.
What would be the best approach to this problem? Putting it in another way, how can I handle transactions without exposing the ISqlMapper?