2010-11-24 8 views
1

J'ai une application qui existe dans trois niveaux de présentation différents: Web, mobile (hors ligne) et Bureau (hors ligne). Les objets métier de base sont les mêmes pour les trois et partagent les mêmes règles de validation et de gestion. Cependant, ils utilisent tous des bases de données différentes (Web - SQL Server 2008, mobile/desktop - SQL Compact). Grâce à un processus de synchronisation, les applications de bureau et mobiles poussent et reçoivent des données de la base de données SQL 2008 du serveur. J'essaye de trouver la meilleure approche à n-tier et je suis un peu coincé. J'ai créé un assembly pour mes objets métier qui encapsule toutes les règles métier. J'aimerais beaucoup que chaque objet de cet assemblage ait une méthode Save(). Cependant, je ne veux pas que cette couche soit au courant d'une couche de données spécifique. Fondamentalement, je veux que les trois couches de présentation peuplent ces objets et appellent la méthode Save(). Mais je souhaite que l'implémentation de la méthode Save() soit différente en fonction de l'application appelante.Conception à niveaux multiples pour le niveau métier commun mais différents niveaux de présentation et de données

J'ai initialement créé une interface appelée IDataAdapter, puis une propriété statique sur chaque objet pour IDataAdapter. Ensuite, la méthode Save() vérifie simplement si elle a été définie, puis transmet l'objet métier à sa méthode Save().

public interface IDataAdapter 
{ 
    void Save(BusinessProxy proxy); 
} 

public class BusinessProxy 
{ 
    public IDataAdapter myAdapter { get; set; } 

    public bool Save() 
    { 
     if (myAdapter == null) 
      throw new Exception(); 
     myAdapter.Save(this); 
    } 
} 

Bien sûr, ce n'est pas idéale, car la couche de présentation aurait besoin d'avoir une référence au niveau de données afin de définir la propriété de l'adaptateur. J'aimerais vraiment avoir une sorte de système de plug-in où je pourrais juste échanger le data.dll en fonction de la plate-forme de l'application.

Quelqu'un at-il des suggestions sur la façon de mettre en œuvre un peu mieux?

Répondre

0

Je suis un grand fan de Simple.

Une chose que vous pourriez faire, est simplement de séparer votre méthode Save à l'ensemble dépendant de la plate-forme. Faites-en simplement une méthode d'extension afin que votre utilisateur final ressemble à une partie de son IDataAdapter. Simple, propre.

0

Vous pouvez utiliser IoC (par exemple structuremap) pour enregistrer les implémentations spécifiques de IDataAdapter dans la couche de présentation.

Une autre approche pourrait être MEF, de sorte que vous pouvez échanger les assemblages quand vous le souhaitez.

1

si vous voulez dire par « la meilleure approche multiniveau » que les différentes couches doivent se connaissent pas et il n'y a qu'une seule méthode qui relient les pièces ensemble vous pouvez créer un global DataAdapter-registre sur la base Où le BusinessProxy peut demander à ce que son IDataAdapter soit utilisé.

 
    public interface IDataAdapter 
    { 
     void Save(BusinessProxy proxy); 
    } 

    public class BusinessProxy 
    { 
     public static DataAdapterRegistry Adapter = new DataAdapterRegistry(); 

     public bool Save() 
     { 
      Adapter.Save(this); 
      return true; 
     } 
    } 

    public class DataAdapterRegistry : IDataAdapter 
    { 
     private Dictionary<Type, IDataAdapter> registry 
            = new Dictionary<Type, IDataAdapter>(); 

     public void Register(Type type, IDataAdapter adapter) 
     { 
      registry[type] = adapter; 
     } 

     public void Save(BusinessProxy proxy) 
     { 
      IDataAdapter adapter; 
       if (registry.TryGetValue(proxy.GetType(), out adapter)) 
        adapter.Save(proxy); 
       else 
        throw new NotSupportedException(proxy.GetType().FullName);  
     } 
    } 

    class Customer : BusinessProxy 
    { 
    } 

    class Order : BusinessProxy 
    { 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      BusinessProxy.Adapter.Register(typeof(Customer), new CustomerAdapter()); 
      BusinessProxy.Adapter.Register(typeof(Order), new OrderAdapter()); 

     } 
    } 

vous pouvez utiliser un cadre "inversion du conteneur de contrôle" comme spring.net de le faire avec des fichiers xml-configurtaion instad de hardcoded-compiletime Initialiser.

Questions connexes