我的问题更多的是架构性质,较少涉及实际实现。
我已经构建了一个基于WCF的API,但无法真正决定如何将PL与BL分开。我已经使我的服务变得精简,因此它只包含最少的实现,例如:
public TagItemResponse TagItem(TagItemRequest request)
{
return (new ItemTagRequestProcessor()).GetResponse(request);
}
当然第一个问题出现了,RequestProcessors 属于哪一层?我认为称它们为外观是错误的,但同时它们与呈现无关。就目前而言,我决定他们仍然属于PL。处理器方法将我的 DTO (DataContracts) 作为输入,验证请求消息(基类),进行身份验证(基类)并最终返回单个 DTO 响应,如下所示:
protected override void Process(TagItemRequest request, TagItemResponse response, Host host)
{
var profile = ProfileFacade.GetProfile(host, request.Profile);
var item = ItemFacade.GetItemId(host, request.Item);
var tags = new List<Tag>();
foreach (var name in request.Tags)
{
var tag = TagFacade.GetTag(profile, name);
ItemFacade.TagItem(item, tag);
tags.Add(tag);
}
ItemFacade.UntagItem(item, tags);
}
现在我问自己,为什么我需要与我的业务对象相关的 1:1 外观类。例如,我有一个 HostFacade,它充当 hostDAO 和处理器之间的层。然而,它几乎没有逻辑,它仅仅处理 DAO 调用。
public static Host GetHost(HostDTO dto)
{
return HostDAO.GetHostByCredentials(dto.Username, dto.Password);
}
问题:我不妨合并处理器和外观,对吗?
我读过很多关于这个主题的文章/书籍,但我仍然无法确定“正确”的方法,并且每次遇到问题时都会选择不同的方法。我想知道是否存在正确的方法。
我找到了 f.ex。 doFactory 示例,他们在服务实现中直接与 DAO 类进行对话。我真的不喜欢这样,因为大多数 ServiceContract 方法共享一些逻辑,因此非常适合与共享基类一起使用。
我还发现了其他示例,其中仅从服务内部调用外观,但这似乎仅适用于非常细粒度的消息。我的消息是“胖”和复合的,以便尽可能减少对服务的调用次数。我的额外处理层似乎是我真正的问题。
关于如何正确分层 WCF 服务,可能没有唯一的答案,但希望你们中的一些人提出的意见要么符合我的直觉,要么为我提供一些关于该主题的新见解。
谢谢!
杰弗里
最佳答案
首先,我假设 PL 您指的是表示层,而不是持久层?
在实现分层应用程序设计时,主要问题应该始终是:我能否在不影响上层实现的情况下替换较低层的实现。
这通常可以通过持久层来最好地说明。例如,如果您从 SQL Server 2008 切换到 MySQL,持久层就会发生变化(当然)。但业务层也有必要改变吗?例如,业务层是否捕获仅由SqlClient抛出的SqlException实例?在一个好的设计中,业务层根本不需要改变。
同样的原则也应该适用于业务层和表示层之间的分离。
在您的示例中,我想说 ItemTagRequestProcessor
不应位于表示层中。首先,它与表示无关,其次,处理请求的实现不是表示层关心的。与 Web 应用程序相比,向客户端呈现 TagItemResponse
是 Web(表示)层的关注点。检索 TagItemResponse
的实例是表示层下面的层的关注点。
决定是否在业务层和持久层之间建立外观是很困难的。我通常不实现外观,因为它添加了额外的(通常是不必要的)间接层。此外,我认为直接从业务层方法调用持久层方法没有问题。如果你考虑到同样的原则:是否可以改变持久层实现而不影响业务层实现。
亲切的问候,
罗纳德·维尔登伯格
关于c# - 以正确的方式分层 WCF 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/661530/