4

我想知道我的解决方案是否存在设计缺陷。这是我所拥有的:

  • Entities=> 纯 poco。参考:没有。
  • Data=> 数据访问。参考:Entities
  • Service=> 业务逻辑。参考:EntitiesData
    • 经理班。
    • 视图模型。
  • WebApp=> 用户界面。参考:EntitiesService

WebAppASP.NET MVC项目作为UI,Entities纯POCO项目无参考。Data访问数据库和Service业务逻辑(我的 Manager 类所在的位置)。

基本上,我Manager为每个实体定义了一个类。例如,我有一个Message与实体列表相关的Recipient实体。我有一个MessageManagerRecipientManager类,负责使用数据层和逻辑结果的 CRUD 操作(例如public List<Message> GetAllMessagesWithPermissionForUser(User user, Permission permission)

对于我的 MVC 项目,我在服务层定义了一些 ViewModel 类来为我的视图生成特定的视频模型。由于视图模型使用管理器类,我在我的服务类中定义了它们。例如,我有一个MessageOperationVM具有PermittedBoxesToSend属性的视图模型。此属性使用我的BoxManager类来获取指定消息允许的所有框:

// Initialized by Catsle Windsor.
public BoxManager BoxManager {get; set;}

public List<Box> PermittedBoxesToSend 
{
    if(this._premittedBoxesToSend != null)
    {
        this._permittedBoxesToSend = BoxManager.GetPermittedBoxesToSend(this.Message);
    }
}
  • 我不确定在 Viewmodels 中使用管理器类是否是一个好的设计。尽管我已将它们定义为构造函数/属性设置器以填充 DI。我应该在我的控制器中填充我的视图模型的属性而不是定义属性并摆脱我的视图模型中的管理器类吗?

    public ActionResult ShowNewMessageDialog()
    { 
        var messageVM = new MessageOperationVM() { new Message() };
        messageVM = this.BoxManager.GetPermittedBoxesToSend();
    }
    
  • 为每个实体使用一个管理器类似乎使维护变得困难。(尽管它们都派生自一个BaseManager共享它们共同操作的类)

  • 上述设计中是否有任何值得一提的重新考虑?

谢谢你。

更新
基于 eulerfx 的回答:
我对您的回答的问题是:要构造 ViewModel,我必须调用一些服务层的方法。所以我不能仅仅基于我的 poco 实体来构建我的 ViewModel。您是否建议我也应该在控制器中构建这些部分?:

public ActionResult ShowNewMessageDialog()
{
    var message = this.messageRepository.GetMessage();
    var messageVM = new MessageViewModel(message);
    messageVM.CustomProperty = this.messageManager.CallSomeMethod(message);
    return View(messageVM);
}
4

2 回答 2

9

我认为从视图模型到服务的引用是一个设计缺陷。视图模型应该是扁平且简单的 DTO,旨在与视图绑定。它们不应该是 DI 容器图的一部分,因为这会使事情复杂化并使对代码的推理更加困难。您正在使用的术语的公认定义如下。

  • 实体是您描述的实体。它们是简单的 POCO 类。
  • 您所说的“数据”是存储库模式。存储库提供对底层数据库中实体的访问和持久性。
  • 服务是一个重载的术语,但是它们通常用于封装域,将其作为 API 暴露给其他应用程序层。服务可以引用存储库。我在 DDD 的上下文中写了一篇关于这些类型服务的博客文章,在这里它们被称为应用程序服务。
  • 视图模型是表示层或您所称的 WebUI 的一部分。因此,它们由 MVC 控制器构造并传递给视图。控制器使用从应用程序服务或直接从存储库获得的数据构造视图模型。视图模型可以包含一个构造函数,该构造函数接受服务或存储库返回的实体。

代码看起来像这样:

/// Domain model class that lives in domain/business layer project
public class Message
{
  // properties and behavior go here
}

// View model class that lives in the ASP.NET project
public class MessageViewModel
{
  public MessageViewModel() { }
  public MessageViewModel(Message message)
  {
    // construct the view model based on the provided entity
  }
  // properties specific to the view go here
} 


// ASP.NET MVC controller.
public class MessagesController : Controller
{
 // this repository should be injected by DI container.
 readonly IMessageRepository messageRepository;

 public ActionResult ShowNewMessageDialog()
 {
   var message = this.messageRepository.GetMessage();
   return View(new MessageViewModel(message));
 }
}
于 2012-04-25T05:08:14.917 回答
1

您可以考虑使用Visitor设计模式来操作Entities和类,而不是 ManagerData类。

如果ManagerorVisitor类的定义使得它们不必仅在 View 代码中使用,那么它不应该是一个问题。但是如果它们只能在视图中使用,而对于其他视图等,您必须重新定义对EntitiesData类的访问权限,或者编写更多/重复的代码,那就有问题了。

于 2012-04-24T07:43:37.107 回答