I've been researching this for weeks. I'm currently designing a loosely-coupled architecture design using n-tier (3-layered) method and factory design approach. My goal is to put each client's business logic (ClientA.DLL, ClientB.DLL) in separate namespaces so that the project scales out, meaning I can modify/remove/add a specific client's business logic without affecting the others, because they're not dependent on each other. Then I invoke the client's namespaces/class using the client's unique identifier (a string value that is maintained in the database) via the Factory namespace. The Factory.DLL also hides the per-client logic, while the BusinessAbstract.DLL serves as the Layout or the Template that the per-client's classes will be using.
Here is the project solution:
And here is the actual code:
BusinessAbstract.DLL
namespace BusinessAbstract
{
// the entity / data transfer object
public class MemberDTO
{
public string MemberID { get; set; }
public string MemberName { get; set; }
}
// the interface
public interface IMaintainable
{
void Add();
void Edit();
void Delete();
}
// the base abstract class, implements the Entity and the Interface
public abstract class Member : MemberDTO, IMaintainable
{
// Implement IMaintanable but change it to abstract
public abstract void Add();
public abstract void Edit();
public abstract void Delete();
// a method with Database access, get from DAL
public virtual MemberDTO GetMemberDetails(params object[] args)
{
return DAL.MemberDAL.FetchMemberDetails(args);
}
public virtual string GetClientBLL()
{
return "base's method";
}
}
}
ClientA implementation of the AbstractBusinessRule
ClientA.DLL
namespace ClientA
{
public class _Member : BusinessAbstract.Member
{
public override void Add()
{
throw new NotImplementedException();
}
public override void Edit()
{
throw new NotImplementedException();
}
public override void Delete()
{
throw new NotImplementedException();
}
public override string GetClientBLL()
{
return "ClientA Method";
}
}
}
The Factory
Factory.DLL
public static class Invoker
{
public static T GetMemberInstance<T>(string clientCode)
where T : Member, IMaintainable
{
Type objType = Type.GetType(clientCode + "._Member," + clientCode);
return (T)Activator.CreateInstance(objType);
}
}
Sample implementation on Presentation Tier
the Website
protected void Page_Load(object sender, EventArgs e)
{
// invoke Member class using String hardcode
Member obj = Invoker.GetMemberInstance<Member>("ClientA");
Response.Write(obj.GetClientBLL()); //prints clientA method
obj = Invoker.GetMemberInstance<Member>("ClientB");
Response.Write(obj.GetClientBLL()); //prints clientB method
}
And you'll also notice that I have a DAL folder in each of the client DLLs as well as the AbstractBusinessRule DLL, because I also want to scale the DAL layer and use the layer structure "UI-BLL-DAL."
Any comments/suggestion about this design are welcome. I'm hoping for input on how I can improve this structure. Thanks in advance.