【问题标题】:asp.net mvc use viewmodels for index or direct domain objects?asp.net mvc 将视图模型用于索引或直接域对象?
【发布时间】:2011-12-14 21:59:21
【问题描述】:

我正在开发一个包含 3 个项目数据、服务和 Web 的 asp.net mvc3 解决方案。我一直在使用接口来尽可能多地抽象服务层,因此网络只知道服务层,而不是保存真正领域模型的数据。 Web 项目使用视图模型并将事物作为分解参数与域对象简单地传递给服务模型。例如创建用户我会使用这样的界面。

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

但是在考虑了一段时间后,我需要返回某种类型的域对象,这需要我在 Web 项目中添加数据引用。

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

所以我认为我有两个选择,要么将我的域对象分解为他们自己的项目,然后所有项目都引用它们,要么可能将数据引用添加到 Web 项目。我认为第一个选项是最好的,但我很好奇是否还有其他选项。谢谢

【问题讨论】:

标签: asp.net-mvc entity-framework repository-pattern


【解决方案1】:

我不会返回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 时特别有用。

【讨论】:

  • 界面太多了。此外,抛出异常而不是创建自己的错误接口。堆栈跟踪是调试器的朋友。
【解决方案2】:

一种方法是创建两个独立的项目,一个用于数据类,一个用于模型/视图模型。

  1. 控制器向服务发出请求
  2. 服务使用您的存储库检索数据对象(即用户)
  3. 手动将用户映射到用户模型或使用http://automapper.codeplex.com/
  4. 将 IEnumerable 返回给控制器。

现在控制器使用 UserModel 而不是 User。这使您的 Web 应用程序不会弄乱您的数据类。

您还可以将服务的接口放入模型项目中,并允许 Rest 服务的消费者访问模型和接口。

【讨论】:

    猜你喜欢
    • 2012-03-14
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    相关资源
    最近更新 更多