I'm attempting to wrap my head around layered application architecture, and after quite a bit of reading on the subject, I've come up with some code that attempts to implement a Data Access Layer / Business Logic Layer / Presentation Layer approach. The code does what I expect, but I would love some feedback on whether I have implemented the idea successfully, or if there are any issues with my thought process.
This is the custom object I'm storing my data in:
public class SalesOrderMetaData
{
private bool isValid;
public bool IsValid
{
get { return isValid; }
set { isValid = value; }
}
}
Presentation Layer:
protected void Page_Load(object sender, EventArgs e)
{
// instatiate the BLL object
SalesOrderBLL salesOrderBLL = new SalesOrderBLL();
// reuest the custom object from the BLL
SalesOrderMetaData salesOrderMetaData = salesOrderBLL.GetSalesOrderMetaData("23447");
// present a value from the custom object to the user
Label1.Text = salesOrderMetaData.IsValid.ToString();
}
Business Logic Layer:
public class SalesOrderBLL
{
public SalesOrderMetaData GetSalesOrderMetaData(string csono)
{
// instantiate the DAL object
SalesOrderDAL salesOrderDAL = new SalesOrderDAL();
// request the custom object from the DAL
SalesOrderMetaData salesOrderMetaData = salesOrderDAL.GetSalesOrderMetaData(csono);
// return the custom object to the PL
return salesOrderMetaData;
}
}
Data Access Layer:
public class SalesOrderDAL
{
public SalesOrderMetaData GetSalesOrderMetaData(string csono)
{
// instantiate the custom object
SalesOrderMetaData salesOrderMetaData = new SalesOrderMetaData();
// retrieve the data from the data source
string sql = "IF EXISTS (SELECT * FROM sosord WHERE csono = @csono) SELECT 1 ELSE SELECT 0;";
SqlParameter param = new SqlParameter("csono", csono);
// set the custom object property based on the retrieved data
// SQLUtilities.GetScalar() is a custom method that returns a SqlCommand.ExecuteScalar() object
salesOrderMetaData.IsValid = Convert.ToBoolean(SQLUtilities.GetScalar(sql,param));
// return the custom object to the BLL
return salesOrderMetaData;
}
}
That is a good start. I would point a few things out though (with the knowledge that you're just learning.. so investigate these as you go):
1) Each layer is currently tightly coupled to the implementations of the layer below it. Generally you would "code against interfaces" in this instance. This means your code is coupled to the contract.. not the implementation. Not a deal breaker because you're learning.. but good to keep in mind.
2) Your data layer is all very custom. You can save yourself a lot of headaches here by investigating the use of an ORM. They take a bit of time to learn.. but WOW are they worth the maintenance hassle.
3) Generally you have Domain Models that represent the domain objects. Alot of the time these correspond directly to database tables. Then in your UI, you have ViewModels that represent the current entity within the View being rendered. This gives you the flexibility to add custom UI-based logic (validation, formatting, etc) in the ViewModels, without the Domain Models ever needing to have such specific UI concerns in them.
If you REALLY want to start thinking about design and architecture (which is fantastic! Kudos for starting to think about that stuff), then you should definitely check out things like:
IoC/Dependency Injection Frameworks
Etc. Again, I commend you on taking the step of actually thinking about your application structure :)