在面向服务的体系结构中开发应用程序时,定义服务调用原型/签名的最佳实践是什么。
例如,我想创建服务电话以发送电子邮件。
假设我的域图层中有以下对象
[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}
我倾向于第一个选项。(说过我知道对象是否复杂,而不是传递整个对象本身。)
答案 0 :(得分:3)
不幸的是,在这种情况下,第二种选择不太清楚,这是因为你的Email class
。
假设我要打电话给你的方法。你让我传递Email
类的一个实例。我去上课合同找到7个房产。
而且,我怎么知道哪些参数是强制性的,哪些是可选的?从文档?如果我必须查阅文档以正确使用API,那么这不是最干净的设计。
我宁愿重构您的电子邮件类,将其调用EmailRequest
并删除所有这些可选参数,然后如果您需要将其用作返回,我会创建另一个类EmailResponse
服务的价值。
答案 1 :(得分:3)
我也投票赞成方法#2。
由于您提到了“面向服务的体系结构”,因此您应该创建一个DataContract
来完全控制客户看到的内容。
此处,序列化是选择加入,因此'未使用的属性'不会通过网络发送。
另外,您还可以获得其他好处,例如控制序列化成员的顺序,指定是否需要字段,自定义名称,版本控制等。它只会让客户明白一切。
此外,DataContractSerializer
据称比XmlSerializer
快10%。有关this博客的更多详情,但我不确定方法#1(原始类型)是否会使用XmlSerializer
或DataContractSerializer
。
[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;}
}
答案 2 :(得分:1)
以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}}
答案 3 :(得分:0)
写两个怎么样?只要拥有第一个,请拨打第二个?
答案 4 :(得分:0)
我会将您的Email
对象设为[DataContract]并使用选项二。我认为你不希望为一种服务方法提供那么多参数。
答案 5 :(得分:0)
SOA的一个重要方面是合同,所以我真的会投票反对用不需要的数据和细节来混淆它,这会导致它快速恶化(呃)。
通道提供的选项非常好,因为它专注于明确地和详细地定义合同,但我还将用于合同目的的类与内部使用的类分开以隐藏和隐藏内部实现细节(我解释这在Edge Component模式中详细说明)