Currently my application's UI layer is coupled to my DAL dll. Dal is initialized like this:
//Initialize Data Access for AS400
Dal = JDE8Dal.Instance;
Dal.conString = Properties.Settings.Default.conAS400;
DAL is desinged as singleton. I thought that forcing the application to have one instance is a good idea.
DAL:
public class JDE8Dal
{
public string conString { get; set; }
private static readonly JDE8Dal _instance = new JDE8Dal();
private JDE8Dal()
{
}
public static JDE8Dal Instance
{
get { return _instance; }
}
// Methods
}
My BLL will look something like this:
namespace YLA.Barcode
{
public static class YlaBarcodeUtil
{
public static string LotStripZeroes(string str)
{
var ret = str;
if (str.Trim().StartsWith("00"))
{
ret = YlaGeneralUtilities.StripLeadingNumofChars(str, 2);
}
return ret;
}
}
public class BarcodeBLL
{
//DAL INIT HERE?
}
}
Now that i need to build more applications i need to move into a 3 layer architecture and start reading on DDD.
1) How to move the DAL handling in BLL? Just add the initialization in my BLL section?
2) Should i keep my DAL design as singleton or not?
You should use the Inversion of Control pattern to reduce the dependency between your layers. In your case I would use a constructor injection as the data context is required by your class:
public class BarcodeBLL
{
private JDE8Dal _context;
public BarcodeBLL(JDE8Dal context)
{
_context = context;
}
}
Data context should be short lived objects. If you're developing a web application you should instantiate one data context per request. I would also recommend using an ORM (Entity Framework / NHibernate).
1: Normally you ahve a infrastructure layer that does the composition.
2: NO BY ALL MEANS. This is bordering "learn programming". Use a IOC container.
//Initialize Data Access for AS400
Dal = JDE8Dal.Instance;
Dal.conString = Properties.Settings.Default.conAS400;
That comment is misleading. This code doesn't actually initialize data access but only sets the database connection string. This should be done in the DAL itself and not in the UI.
public class JDE8Dal
{
public string conString { get; set; }
private static readonly JDE8Dal _instance = new JDE8Dal();
private JDE8Dal()
{
}
public static JDE8Dal Instance
{
get { return _instance; }
}
// Methods
}
Layers aren't usually defined this way, the DAL is an assembly/dll, not a class. As you wrote it, it seems like you want a God Object where all persistence logic is defined. Classes in the Data Access Layer are much more fine grained and specialized : for instance Repositories/DAO's manage persistence of one particular domain object.
In addition, it's generally not a good idea to resort to a Singleton "just because it feels right to have only one instance". And especially not a mutable singleton. In your example, anyone can change Dal.Instance.conString
, with potentially dramatic consequences on other consumers of the singleton. Among other drawbacks.
Even if there's likely to ever be one implementation of your DAL (AS400 as it seems), it's a good idea in projects of reasonable complexity to use dependency injection for unit testing purposes. DI enables you to easily substitute your concrete DAL object implementations for fake DAL objects that are much more lightweight and useful in unit tests.
public class BarcodeBLL
{
//DAL INIT HERE?
}
Non, no DAL init here ;)
The business logic layer (Domain layer in DDD) shouldn't have a reference to the DAL, the DAL should have a reference to the BLL. A domain object shouldn't know how to persist itself (Persistence Ignorance principle) because it would have too many responsibilities (Single Responsibility Principle) and that would create a tight coupling between the BLL and the DAL, making it very awkward to reuse and maintain the BLL.