asp.net mvc использовать viewmodels для индексных или прямых доменных объектов? - PullRequest
0 голосов
/ 15 декабря 2011

Я работаю над решением asp.net mvc3, которое имеет 3 проекта: Data, Service и Web.Я использовал интерфейсы для максимально возможного абстрагирования сервисного уровня, чтобы сеть знала только о сервисном уровне, а не о Данных, где хранятся истинные доменные модели.Веб-проект использует модели представлений и просто передает вещи в сервисную модель как выделенные параметры против объекта домена.Например, при создании пользователя я бы использовал такой интерфейс.

public interface IUserService
{
    void CreateUser(string userName, string firstName, string lastName....);
}

Но, подумав некоторое время о чем-то наподобие GetUsers, мне нужно вернуть объект домена какого-то типа, и этопотребует, чтобы я добавил ссылку на данные в веб-проекте.

 public interface IUserService
{
    void CreateUser(string userName, string firstName, string lastName....);
    **IEnumerable<User>** GetUsers();
}

Так что я думаю, что у меня есть два варианта: либо разбить мои доменные объекты на их собственный проект, на который затем ссылаются все проекты, либо, возможно, добавить ссылку на данные в веб-проект.Я думаю, что первый вариант самый лучший, но мне любопытно, есть ли другие варианты.Спасибо

Ответы [ 2 ]

2 голосов
/ 15 декабря 2011

Вместо того, чтобы возвращать User, я бы:

// MyCompany.Data Project
public interface IUserService 
{ 
  IUserServiceResult<IUser> CreateUser(IUser User); 
  IUserServiceResult<IEnumerable<IUser>> GetUsers(); 
} 

public interface IUserServiceResult<T>
{
  bool IsSuccessful { get; }
  string UserErrorMessage { get; }
  T Data { get; }
}

public interface IUser
{  // Some Getter Properties
}

// MyCompany.Service
public class UserService : IUserService
{
  public UserServiceResult<User> CreateUser(IUser User)
  {  
      var result = new UserServiceResult<User>();

      if (User == null)
      {
        // log the error AND
        result.UserErrorMessage = "User information was not valid.";

        // or
        throw new ArgumentNullException("User");
      }

      // example only
      result.IsSuccessful = 
        (Context.Users.FirstOrDefault(x => x.Email == User.Email) == null)

      if (result.IsSuccessful)
      {
          User newUser;
          // create user...
          result.Data = newUser; 
      }

      return result;
  }
  public IUserServiceResult<IEnumerable<IUser>> GetUsers()
  {
    // Similar to above, can check for authentication
    // Maybe return IsSuccessful = false, 
    // UserErrorMessage = "Requires administrative privileges".

    // or result.Data = new List<User>();
  }
}

public class UserServiceResult<T> : IUserServiceResult<T>
{
  bool IsSuccessful { get; set; }
  string UserErrorMessage { get; set; }
  T Data { get; set; }
}

public class User : IUser { }  //

Мне нравится, когда сервис или уровень данных всегда возвращают тип результата с типизированными типизированными данными. Я нахожу это особенно полезным при передаче его обратно в jQuery.

1 голос
/ 15 декабря 2011

Один из способов сделать это - создать два отдельных проекта, один для вас, Классы данных, и другой для ваших Моделей / ViewModels.

  1. Контроллер отправляет запрос в службу
  2. Служба извлекает объекты данных (пользователь IE) из вашего хранилища
  3. Либо вручную сопоставьте пользователя с пользовательской моделью, либо используйте http://automapper.codeplex.com/
  4. Верните IEnumerable в контроллер.

Теперь контроллер работает с UserModel вместо User.Это предотвращает путаницу в вашем веб-приложении с вашими классами данных.

Вы также можете добавить интерфейсы для своего сервиса в проект моделей и предоставить потребителям сервиса Rest доступ к моделям и интерфейсам.

...