2009-09-12 15 views
-1

Tout en divisant mon application C# en couches, j'ai résolu le problème de la dépendance circulaire entre les couches de la manière suivante:Impossible d'obtenir des données de la couche DA. Que faire?

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

S'il vous plaît jeter un oeil à la MyClassDA de classe dans la couche DA et l'assemblée elle-même.

Comment une méthode MyDA.Get() peut renvoyer des objets de type MyClass lorsque la couche d'accès aux données ne connaît pas le type MyClass.

Si ce design n'est pas efficace, Comment puis-je le changer/le modifier?

+1

C'est une question incroyablement mal formulée. J'ai lu ton autre post mais je n'ai aucune idée de ce que tu cherches. Pouvez-vous le reformuler en précisant votre problème plus spécifiquement? –

+0

Moi aussi, je n'ai aucune idée de ce que vous demandez. Quel est le code censé représenter? Je ne vois pas de classe UserDA nulle part. Que signifie "les instances d'interface ne peuvent pas être des choses avec des données récupérées par un SqlDataReader"? –

+0

Dans quelle partie rencontrez-vous un problème? Ne savez-vous pas comment accéder aux données? –

Répondre

1

Pour autant que je peux comprendre que vous avez une relation bidirectionnelle entre votre DA et de la couche d'affaires. Pour résoudre ce problème, je suggère que vous devriez avoir 3 couches au lieu de deux. Je veux dire que vous devriez avoir une couche Model qui modélise simplement les objets DB, puis vous pouvez dériver des classes de modèle dans votre couche Business et ajouter d'autres comportements comme la méthode Save.

Voici ce que je veux dire:

//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); 
} 
} 
} 

J'utilise un décorateur pour combiner l'utilisateur et UserDao comme un objet de modèle de domaine.

+0

Qu'est-ce que vous faites personnellement pour diviser votre application entre les couches tout en gardant la dépendance circulaire à l'écart? – anonymous

+0

En fait, je ne combine pas mon modèle avec la fonctionnalité d'accès aux données. Les classes de modèle ne connaissent pas DataAccess – Beatles1692

1

L'une des raisons pour lesquelles les gens font des objets ignorant la persistance (POCO) est d'éviter un tel scénario. Il n'y a tout simplement aucun moyen pour la couche d'accès aux données d'avoir une référence à une classe qu'elle ne connaît pas - il est préférable que la classe ignore l'accès aux données. La seule façon de faire cela est d'implémenter Get() sur User au lieu de UserDA. Vous pouvez faire quelque chose comme ceci:

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(), 
    }; 
    } 
} 
+0

Comment devrais-je changer l'architecture pour obtenir un meilleur design? – anonymous

+0

Je suis un grand fan de la façon dont Sharp Architecture le fait: http://sharparchitecture.net/ télécharger les fichiers et chercher le document là-bas - il a une longue description du modèle le processus est également décrit généralement dans cet article : http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx Fondamentalement, vous avez un objet d'accès aux données dans le DAL avec des méthodes non statiques comme UserDao.GetById (int id): User et UserDao.Save (Utilisateur utilisateur). L'utilisateur ne sait rien sur les problèmes de persistance - il décrit SEULEMENT l'objet métier utilisateur –

+0

Chaque UserDao est également basé sur IUserDao.L'interface est dans la couche domaine et la couche DA dépend du domaine (mais le domaine ne dépend pas de l'agent DA). Si vous en avez vraiment besoin, vous pouvez avoir des objets métier à l'aide d'IUserDao et l'implémentation spécifique leur est injectée depuis une couche supérieure. Par ailleurs, tout au long des articles décrivant ce modèle, les termes DAO et Repository sont utilisés de manière quelque peu interchangeable, bien que les DDD hardcore prétendent qu'il existe une différence réelle. –