简体   繁体   中英

3 layer architecture in a Winform App

I'm trying to implement this architecture for the first time in a Winform. So I have a simple but very important question for me. Take a simple example. I want the form to retrieve a user list and to allow a modification of the phone number. I have this for the first step (simplified and I normally use interfaces)

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

Now by selecting a user in the lisbox, I'm able to display some information as the Phone number. When I'm changing the phone number, I need a method called UpdatePhoneNumber to update the SQL database. But, where to place it? User or UserService (I don't talk about the SQL query, just the logic) And after that, how to access (here or somewhere else in the app) to this user property to display it in the form? Directly with _user.Id (User must be instantiated in the form) or implement a _userService.The id which retrieves User.ID (in this case Form knows only UserService class). Many thanks for your precious help

Put all Methods working on the User's data in the user class. Ask yourself the question what the user can do? Put all the logic which controlls the users in UserService like GetUserById, GetAllUsers, CreateUser and so.. Put all the method which the user can perform in the User class. Or lately i was building such kind of thing and i merged User and UserServices into one and made the UserServices class method static so i can access them without instantion of the User.

Hope this help.

Here is what your basic 3-layered app looks like.

  1. UI (your form and ui supporting objects)
  2. BLL (GetAllUsers, SaveUser, DeleteUser, etc)
  3. Data (ADO, EF, etc)

In your particular case, you really looking for Master-detail concept. A master usually the one where you display list of users

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

I will not discuss it here but you can set bindings so that click on grid will result in detail control being populated. Or manually

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

Now, of course, you're about to change the text box and save user...

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

This is general idea, how this is done. If you follow, you have distinct layers. UI calls Service, which calls Data. For example, you have BLL

// Service
private IUserDataProvider _provider;

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

your provider might return some unwanted data, so you can use BLL to trim it and return only appropriate data. But you don't know what provider is doing inside. May be it is doing Ado.net or Entity Framework. Hence a true separation of layers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM