我想知道我的解决方案是否存在设计缺陷。这就是我所拥有的:
Entities
=>纯poco。 refs:none。Data
=>数据访问。参考:Entities
。Service
=>商业逻辑。参考:Entities
和Data
WebApp
=> UI。参考:Entities
和Service
WebApp
ASP.NET MVC项目作为UI,Entities
项目没有参考来保存纯POCO。 Data
访问数据库,Service
访问Business Logic(我的Manager类所在的位置)。
基本上,我为每个实体定义了一个Manager
类。例如,我有一个与Message
实体列表相关的Recipient
实体。我有一个MessageManager
和RecipientManager
类,负责使用数据层和逻辑结果的CRUD操作(例如public List<Message> GetAllMessagesWithPermissionForUser(User user, Permission permission)
)
对于我的MVC项目,我在Service层中定义了一些ViewModel类,为我的视图生成特定的视频模型。由于视图模型使用的是Manager类,因此我在我的服务类中定义了它们。例如,我有一个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中使用管理器类是否是一个好的设计。虽然我已经将它们定义为构造函数/属性setter以填充DI。我应该在控制器中填充我的viewmodels属性而不是定义属性并在我的ViewModels中删除管理器类吗?
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);
}
答案 0 :(得分:9)
我会考虑视图模型中的引用来为设计缺陷提供服务。视图模型应该是扁平的,简单的DTO用于与视图绑定。它们不应该是DI容器图的一部分,因为这会使事情复杂化并使代码的推理变得更加困难。您使用的术语的可接受定义如下。
代码看起来像这样:
/// 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));
}
}
答案 1 :(得分:1)
您可以考虑使用Visitor
设计模式来操作Entities
和Data
类,而不是Manager类。
如果Manager
或Visitor
类定义为不必仅在View代码中使用,那么它不应该是一个问题。但是,如果它们只能在视图和其他视图等中使用,则必须重新定义对Entities
和Data
类的访问权限,或者编写更多/重复的代码,然后才会出现问题。< / p>