First, you create a single place in the data layer for getting connection information. This might be a private member if your data layer is confined to a single class, or internal item if the layer encompasses an entire assembly. It could return a connection string or an actual connection object itself, but the main thing is that it's not exposed outside the data layer at all:
private static ConnectionString { get { // read from config file once.... return ""; } }
private SqlConnection getConnection()
{
SqlConnection result = new SqlConnection(ConnectionString);
result.Open(); // I like to open it in advance, but that's less common
return result; // you'll want some error handling code in here as well
}
You then provide public methods in the data layer that match the interface you want to provide to the business layer. In a well-designed app this will generally match the stored procedures, and that sounds like what you're going for, but sometimes it doesn't quite work work out so well. For example, you may need to call multiple procedures from one method.
Whatever you do, the method should accept strongly-typed parameters values for use when calling the procedures. There's some debate about whether the method should return a business object or a datarecord. Personally, I tend to favor returning a datarecord, but providing an additional "layer" where the datarecords are translated to strongly-typed business objects:
public IDataRecord GetXYZ(int id)
{
DataTable dt = new DataTable();
using (var cn = getConnection())
using (var cmd = new SqlCommand("getXYZ"))
{
cmd.CommandType = CommandTypes.StoredProcedure;
cmd.Parameters.Add("@ID", SqlDbType.Int).Value = id;
using (var rdr = cmd.ExecuteReader())
{
dt.Load(rdr);
}
}
//obviously put a little more work into your error handling
if (dt.Rows.Count <= 0)
throw new Exception("oops");
return dt.Rows[0];
}
public class XYZFactory
{
public static XZY Create(IDataRecord row)
{
XYZ result = new XYZ();
result.id = row["ID"];
result.otherfield = row["otherfield"];
return result;
}
}