我的问题更多是架构性的,较少涉及实际的实现。
我已经建立了基于WCF的API,但无法真正决定如何将PL与BL分开。我已经使我的服务变薄了,因此它只保留了最少的实现,例如:
public TagItemResponse TagItem(TagItemRequest request)
{
return (new ItemTagRequestProcessor()).GetResponse(request);
}
当然比第一个问题产生了,RequestProcessor属于哪一层?我认为称它们为外观是错误的,但与此同时,它们与外观无关。至于现在,我决定他们仍然属于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/