【问题标题】:Designing WCF data contracts and operations设计 WCF 数据契约和操作
【发布时间】:2011-01-25 00:00:34
【问题描述】:

我现在开始设计一个 wcf 服务总线,它现在很小,但会随着我们业务的增长而增长,所以我担心一些日益严重的问题,也尽量不要过多地使用 YAGNI。这是一个电子商务平台。问题是我对把东西放在哪里有太多的第二个想法。我将给出一个场景来演示我所有的问题。

我们有一个销售产品并最终交付产品的电子商务网站。为此,我们有一个 PlaceOrder 服务,除其他参数外,它还需要一个 Address 对象,在这种情况下(我们的网站下订单)由 City、Street 和 ZipCode 组成。

我们还与仅使用我们的平台销售产品的合作伙伴开展业务。他们负责送货。对于这种情况,我们有一个 PlaceOrderForPartner 服务,除其他对象外,它还需要一个 Address 对象。但是,在这种情况下(合作伙伴下订单),地址对象由仅与合作伙伴下的订单相关的不同信息组成。

鉴于这种情况,我有几个问题:

1) 如何在我的解决方案的命名空间和文件夹中组织这个 DataContracts 对象?我考虑过为每个上下文(合作伙伴、客户等)创建一个文件夹来保存服务和 DataContract。

所以我会的

- 我的解决方案.sln - 合作伙伴(文件夹) -PartnetService.svc - 数据合同(文件夹) - 地址 - 客户(文件夹) - 客户.svc - 数据合同(文件夹) - 地址

使用这种方式,我将拥有一个命名空间来放置所有特定于上下文的数据合同。

2) 服务设计呢?我是否应该为每个可能下订单的服务创建一个服务,并在其中创建一个 PlaceOrder 方法,如下所示:

Partner.svc/PlaceOrder
Customer.svc/PlaceOrder

或使用 PlaceOrderForPartner 和 PlaceInternalOrder 创建一个订单服务,如下所示:

Order.svc/PlaceOrderForPartner
Order.svc/PlaceOrderForCustomer

3) 假设我在最后一个问题中选择了第一个选项,那么我应该如何处理订单上进行的合作伙伴和客户共同的操作?

4) 我应该将 DataContracts 和 Service 定义放在同一个程序集中吗?每人一份?服务实现的一切?

5) 如何命名操作的输入和输出消息?我应该使用实体本身还是使用 OperationNameRequest 和 OperationNameResponse 模板?

最重要的问题是:如何“组织”服务创建中涉及的数据合同和服务?

提前感谢您对此的任何想法!

【问题讨论】:

    标签: wcf service soa


    【解决方案1】:

    除了 TomTom 提到的,我还想在此处添加我的 2 美分:

    我喜欢这样构建我的 WCF 解决方案:

    合同(类库)
    包含所有服务、操作、故障和数据合同。可以在纯 .NET-to-.NET 场景中在服务器和客户端之间共享

    服务实现(类库)
    包含实现服务的代码,以及实现此目的所需的任何支持/帮助方法。没有别的了。

    服务主机(可选 - 可以是 Winforms、控制台应用程序、NT 服务)
    包含用于调试/测试或可能还用于生产的服务主机。

    这基本上给了我服务器端的东西。

    在客户端:

    客户端代理(类库)
    我喜欢将我的客户端代理打包到一个单独的类库中,以便它们可以被多个实际的客户端应用程序重用。这可以使用 svcutil 或“添加服务引用”并手动调整生成的可怕的 app.config 来完成,或者通过使用 ClientBase<T>ChannelFactory<T> 构造手动实现客户端代理(共享合同程序集时)。

    1-n 个实际客户(任何类型的应用)
    通常只会引用客户端代理程序集,或者也可能会引用合同程序集,如果它被共享的话。这可以是 ASP.NET、WPF、Winforms、控制台应用程序、其他服务 - 你可以命名它。

    这样;我有一个漂亮而干净的布局,我一遍又一遍地使用它,我真的认为这让我的代码更干净,更容易维护。

    这受到了 Miguel Castro 在 DotNet Rocks TV 上与 Carl Franklin 合作的 Extreme WCF screen cast 的启发 - 强烈推荐屏幕演员!

    【讨论】:

      【解决方案2】:

      你从最高级别开始就错了。

      • 不应该是“PlaceOrder”服务,而是“OrderManager”。也许你以后想添加更多的服务功能——比如查询订单、取消订单、更改订单——谁知道呢。一般来说,我会尽量减少“服务”(.svc)的数量并在那里添加方法。否则,您最终会因在代码中使用它们而产生巨大的开销 - 没有任何真正的好处。

      • 为什么要分开合作伙伴和客户?我敢肯定,通过 15 分钟的数据设计,您可以将事情完全分解为一个数据结构,这样您就可以只拥有一项服务。如果不是...在一个接口上使用这两种方法,请受安全性限制。但我真的不喜欢两个程序。而是有两个地址字段——“Address”和“PartnerInfo”,并且只能设置一个(其他必须为null),在逻辑中检查。

      • 分成两个项目。接口,数据合约进入一个单独的项目(blabalbla.Api),以便客户可以根据需要实际获取 DLL - 至少它使您的事情变得更容易,您可以依赖“共享类型”,无需在内部生成包装器。允许更好的测试(因为子项目不要忘记重新生成包装器......这可能会在测试它们时导致错误)。

      • 我总是将实现放入“blabla.Service”项目中。网址将是子域中的“Services.blabla.com/”(或“api.blabla.com”,主要取决于心情,但最近我主要使用 api) - 将内容与主网站分开。

      【讨论】:

      • 我对最新的 2 个回复没意见,但对前 2 个回复不满意。我阅读了一些指南(包括来自 microsoft 和 Juval Lowy 的指南),其中指出您在一个操作中不应超过 12 个操作服务并使它们与上下文相关联。不分离数据合约的另一个问题是,我最终可能会得到从不同字段读取的具有相同签名的所有服务,这不是很语义化。
      猜你喜欢
      • 2011-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多