在面向服务的体系结构中为服务调用定义方法签名的最佳实践是什么?

在面向服务的体系结构中开发应用程序时,定义服务调用原型/签名的最佳实践是什么。

例如,我想创建服务调用以发送电子邮件。

假设我的域层中有以下对象

[datacontract] public class Email { public string To { get; set; } public string From { get; set; } public string Message { get; set; } public string Subject { get; set; } //I am not going to use this properties in send email method public string OtherProp1 {get; set;} public string OtherProp2 {get; set;} public string OtherProp3 {get; set;} } 

我应该创建服务方法签名吗?

  public bool SendEmail(string from,string to, string subject,string message){//My Logic}} 

要么

  public bool SendEmail(Email myEmail){//My Logic} 

我倾向于第一个选项。(已经说过,我知道对象是否复杂,而不是传递整个对象本身。)

不幸的是,在这种情况下,第二种选择不太明确,这是因为您的Email class

假设我打电话给你的方法。 你让我传递了一个Email类的实例。 我去上课合同,找到7个房产。

而且,我怎么知道哪些参数是强制性的,哪些是可选的? 来自文档? 如果我必须查阅文档以正确使用API​​,那么这不是最干净的设计。

我宁愿重构您的Email类,将其EmailRequest ,删除所有这些可选参数,然后如果您需要将其用作服务的返回值,我将创建另一个类EmailResponse

我也投票选择方法#2。

既然您提到了“面向服务的体系结构”,那么您应该创建一个DataContract来完全控制客户看到的内容。

这里,序列化是选择加入,因此’未使用的属性’将不会通过线路发送。

此外,您还可以获得其他好处,例如控制序列化成员的顺序,指定是否需要字段,自定义名称,版本控制等。 它只会让客户明白一切。

此外, DataContractSerializer据称比XmlSerializer快10%。 关于这个博客的更多细节,虽然我不确定方法#1(原始类型)是否会使用XmlSerializerDataContractSerializer

 [DataContract(Name="MyEmail", Namespace="http://contoso.org/soa/datacontracts")] public class Email { [DataMember(Name="ToField", IsRequired=true, Order=0] public string To { get; set; } [DataMember(Name="FromField", IsRequired=false, Order=1] public string From { get; set; } [DataMember(Name="MessageField", IsRequired=true, Order=2] public string Message { get; set; } [DataMember(Name="SubjectField", IsRequired=false, Order=3] public string Subject { get; set; } public string OtherProp1 {get; set;} public string OtherProp2 {get; set;} public string OtherProp3 {get; set;} } 

以OOP方式总是更好。 如果电子邮件类过多,请尝试分析并定义另一个解决方案。 像这样

  public class Email { //everything needed for service is extracted in another class public EmailAddressDetails {get;set} //I am not going to use this properties in send email method public string OtherProp1 {get; set;} public string OtherProp2 {get; set;} public string OtherProp3 {get; set;} } 

并使用这样的服务

  public bool SendEmail(EmailAddressDetails email){//My Logic}} 

写两个怎么样? 只是拥有第一个,拨打第二个?

我会将您的Email对象设为[DataContract]并使用选项二。 我认为你不希望一个服务方法有那么多参数。

SOA的一个重要方面是合同,所以我真的会投票反对用不需要的数据和细节来混淆它,这会导致它快速恶化(呃)。

由channs提供的选项非常好,因为它专注于明确地和详细地定义契约,但我还将用于合同目的的类与内部使用的类分开以隐藏和隐藏内部实现细节(我详细解释了这一点)在边缘组件模式中)