以正确的方式分层WCF服务

时间:2009-03-19 09:19:45

标签: c# wcf architecture n-tier-architecture

我的问题更多的是建筑性质,与实际实施的关系较少。

我已经基于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服务,可能没有单一的答案,但希望你们中的一些人有一个意见,要么符合我的直觉,要么为我提供一些新的主题。

感谢名单!

杰弗里

1 个答案:

答案 0 :(得分:3)

首先,我假设PL表示表示层,而不是持久层?

实现分层应用程序设计时,主要问题应该是:我可以替换较低层的实现,而不会影响上面层的实现。

这通常由持久层最好地说明。例如,如果从SQL Server 2008切换到MySQL,则持久层会发生变化(当然)。但业务层的变化是否也必要?例如,业务层是否捕获仅由SqlClient抛出的SqlException实例?在良好的设计中,业务层根本不需要进行任何更改。

同样的原则应该适用于业务层和表示层之间的分离。

在您的示例中,我会说ItemTagRequestProcessor不应该在表示层中。首先,它与表示无关,其次,处理请求的实现不是表示层的关注点。将其与Web应用程序进行比较,向客户端呈现TagItemResponse是Web(表示)层的关注点。检索TagItemResponse的实例是表示层下面的图层的关注点。

确定在业务层和持久层之间是否有外观是很困难的。我通常不实现外观,因为它增加了一个额外的(通常是不必要的)间接层。此外,我没有看到直接从业务层方法调用持久层方法的问题。如果只考虑相同的原则:是否可以在不影响业务层实现的情况下更改持久层实现。

亲切的问候,

罗纳德威尔登伯格