Question

While dividing my C# application in layers, I have solved the problem of circular dependency among layers in the following way:

using System;
using System.Collections.Generic;
using System.Text;

using SolvingCircularDependency.Common;
using SolvingCircularDependency.DA;

namespace SolvingCircularDependency.BO
{
    public class MyClass : IPersistent
    {
        private string _message;
        public string Message
        {
            get { return _message; }
            set { _message = value; }
        }

        public bool Save()
        {
             return MyClassDA.Save(this);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Text;

namespace SolvingCircularDependency.Common
{
    public interface IPersistent
    {        
        bool Save();
        string Message { get;}
    }
}

using System;
using System.Collections.Generic;
using System.Text;

using SolvingCircularDependency.Common;

namespace SolvingCircularDependency.DA
{
    public class MyClassDA
    {
        public static bool Save(IPersistent obj)
        {
            Console.WriteLine(obj.Message);

            return true;
        }
    }
}

using System;
using System.Collections.Generic;
using System.Text;

using SolvingCircularDependency.BO;

namespace SolvingCircularDependency.UI
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myobj = new MyClass();
            myobj.Message = "Goodbye Circular Dependency!";
            myobj.Save();

            Console.ReadLine();
        }
    }
}

alt text

Please take a look at the class MyClassDA in the DA layer and the assembly itself.

How can a MyDA.Get() method return objects of type MyClass when the Data Access layer doesn't know about the MyClass type.

If this design is not efficient, How can I change/modify it?

Was it helpful?

Solution

As far as I can understand you have a bidirectional relationship between your DA and Business layer. To solve this problem I suggest that you should have 3 layers instead of two. I mean you should have a Model layer that simply model the DB objects ,then you can derive from model classes in your Business layer and add other behaviors like Save method.

Here's what I mean:

//Model Layer
public class UserModel
{
public virtual string Firstname{get;set;}
}
//DataAccess Layer
public class UserDao
{
List<UserModel> GetAll();
}
//BusinessLayer
public class UserDomainModel:UserModel
{
public UserDomainModel(UserModel user,UserDao dao)
{
_user=user;
_dao=dao;
}
public override string FirstName
{
get
{
return _user.FirstName;
}
set
{
_user.FirstName=value;
}

public void Save()
{
_dao.Save(_user);
}
}
}

I'm using a decorator to combine User and UserDao as a domain model object.

OTHER TIPS

One of the reasons people do Persistance Ignorant objects (POCO) is to avoid such a scenario. There is simply no way for the data access layer to have a reference to a class that it doesn't know about - it is much better to have the class not know about the data access.

The only way you can really do this is to implement Get() on User instead of on UserDA. You can do something like this:

public class User {
  IGetFromPresistance<User> _userFetcher;
  public static IList<User> GetMatching(Specification<User> spec) {
    var values = _userFetcher.Find(spec);  //Returns a DataRow or IDictionary<string, object>
    return new User() {
      PhoneNumber = new PhoneNumber(values["phone"].ToString()),
      Name = values["name"].ToString(),
    };
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top