2017-10-13 13 views
0

J'essaye d'implémenter cette architecture pour la première fois dans un Winform. J'ai donc une question simple mais très importante pour moi. Prenons un exemple simple. Je veux que le formulaire récupère une liste d'utilisateurs et permette une modification du numéro de téléphone. J'ai cela pour la première étape (simplifié et j'utilise normalement des interfaces)Architecture à 3 couches dans une application Winform

public Form1() 
{ 
    InitializeComponent(); 
    UserService _userService = new UserService(); 
    listBoxUsers.DataSource = _userService.GetAllUsers(); 
} 
class User 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Phone { get; set; } 
} 
class UserService 
{ 
    UserRepository _userRepository=new UserRepository(); 
    public Dictionary<int, string> GetAllUsers() 
    { 
     DataTable dtbl= _userRepository.AllUsers(); 
     //Some code here 
     return dict; 
    } 
} 
class UserRepository 
{ 
    public DataTable AllUsers() 
    { 
     //Sql query 
     return dtbl; 
    } 
} 

Maintenant, en sélectionnant un utilisateur dans le lisbox, je suis en mesure d'afficher des informations comme le numéro de téléphone. Quand je change le numéro de téléphone, j'ai besoin d'une méthode appelée UpdatePhoneNumber pour mettre à jour la base de données SQL. Mais, où le placer? Utilisateur ou UserService (je ne parle pas de la requête SQL, juste la logique) Et après cela, comment accéder (ici ou ailleurs dans l'application) à cette propriété de l'utilisateur pour l'afficher dans le formulaire? Directement avec _user.Id (l'utilisateur doit être instancié dans le formulaire) ou implémenter un _userService.The identifiant qui récupère User.ID (dans ce cas, le formulaire ne connaît que la classe UserService). Un grand merci pour votre aide précieuse

+1

Pourquoi 'GetAllUsers()' renvoie-t-il un 'Dictionary '? Je m'attendrais à un 'Dictionary ' (ou même juste un 'IEnumerable '). 'User' est * juste * un objet de transfert de données.Ainsi, lorsque vous changez le numéro de téléphone * ou toute autre propriété *, modifiez-le simplement dans le DTO, puis utilisez une méthode comme Update (utilisateur utilisateur) dans le service et dans le référentiel. Le service chargé de vérifier si quelque chose a changé du tout et le référentiel d'écrire réellement les modifications apportées à la base de données (ou tout type de stockage). – Corak

Répondre

0

Mettez toutes les méthodes qui fonctionnent sur les données de l'utilisateur dans la classe d'utilisateurs. Posez-vous la question de ce que l'utilisateur peut faire? Mettez toute la logique qui contrôle les utilisateurs dans UserService comme GetUserById, GetAllUsers, CreateUser et ainsi de suite. Mettez toute la méthode que l'utilisateur peut effectuer dans la classe User. Ou récemment, je construisais ce genre de chose et j'ai fusionné User et UserServices en un seul et rendu la méthode de classe UserServices statique afin que je puisse y accéder sans l'installation de l'utilisateur.

Espérons cette aide.

+0

"Fusionner" 'User' et' UserService' est l'exact opposé de l'intention de séparer la logique en couches. Il viole également le [principe de responsabilité unique] (https://en.wikipedia.org/wiki/Single_responsibility_principle) (le "S" dans [SOLID] (https://en.wikipedia.org/wiki/SOLID_ (object- orienté_design))) – Corak

+0

Cela n'a de sens que sur un grand projet et il ne viole toujours pas le principe du respect unique cuz tout en rapport avec la logique des utilisateurs est dans l'utilisateur. –

+0

Il semblait que OP voulait «entrer dans» l'architecture en couches en l'appliquant d'abord à une petite application de test pour savoir ce qui fonctionne et ce qui ne fonctionne pas, et peut-être plus tard l'utiliser dans des projets plus volumineux. Et avoir un objet responsable de sa propre récupération/persistance ** est ** une violation du SRP. Vous n'avez pas une classe "App" et mettez tout dedans, juste parce que "tout est lié à la logique des applications". – Corak

0

Voici à quoi ressemble votre application de base à 3 couches.

  1. UI (votre formulaire et les objets de support de Ui)
  2. BLL (GetAllUsers, SaveUser, DeleteUser, etc.)
  3. données (ADO, EF, etc.)

Dans votre cas particulier, vous cherchez vraiment le concept Master-detail. Un maître généralement celui où vous affichez la liste des utilisateurs

// Master 
var _userList = Service.GetAllUsers(); // List<UserModel> 
userGrid.Datasource = _userList; 

Je ne parlerai pas ici mais vous pouvez définir des liaisons de sorte que cliquez sur la grille entraînera le contrôle de détail étant peuplé. Ou manuellement

// detail 
UserModel model = master._userList[currIndex]; 
txtFirstName.Text = model.FirstName; 
txtPhone.Text = model.Phone; 
// . . . . 

Maintenant, bien sûr, vous êtes sur le point de changer la zone de texte et enregistrer l'utilisateur ...

// detail 
UserModel model = master._userList[currIndex]; 
Service.SaveUser(model); 
Master.Reload(); 

Cette idée générale est, comment cela se fait. Si vous suivez, vous avez des couches distinctes. L'interface utilisateur appelle le service, qui appelle des données. Par exemple, vous avez BLL

// Service 
private IUserDataProvider _provider; 

public List<UserModel> GetAllUsers() 
{ 
    var data = _provider.Get<User>(); 
    // massage your 'data' and return List<UserModel> 
    . . . . 
} 

votre fournisseur peut renvoyer des données non désirées, de sorte que vous pouvez utiliser BLL pour couper et retourner uniquement les données appropriées. Mais vous ne savez pas ce que le fournisseur fait à l'intérieur. Peut-être que c'est en train de faire Ado.net ou Entity Framework. D'où une véritable séparation des couches.