WCF Contracts without the annotations
我想知道是否有任何方法可以在不使用[datacontract]和[datamember]注释的情况下定义WCF契约类。原因是我们目前拥有的域模型相当干净,所以我们希望保持这种方式。这里的最佳实践是什么?创建一个传输对象并将域模型对象复制到一个传输对象中(该对象具有所需的注释,并且契约是否在客户端和服务器之间传输)?或者不以其他方式注释对象模型和指定契约。
如果不向类添加任何序列化属性,并将其用作WCF服务约定方法的一部分,则WCF无论如何都将使用默认序列化规则生成数据约定。这意味着类将隐式地成为
您唯一需要应用这些属性的时间是您是否要重写默认行为,例如隐藏一些属性、应用名称空间等。通常认为这样做是一种良好的做法,因为依赖默认行为可能会在以后给您带来麻烦。(它还明确表示您的类是为WCF使用的)。但是,只要默认行为满足您的需要,就不必严格要求它。
针对您的后续行动:
据我所知,没有完全外部的方法来更改给定类的
或者,您可以通过执行您在问题中建议的操作来绕过整个问题:不要序列化域对象,而是创建自定义DTO对象并将其序列化。例如,每当我使用实体框架时,我都倾向于这样做,因为序列化那些框架可能很困难。如果您的域对象有许多内置的行为,那么这也是一种很好的方法——您可以清楚地将"数据传递"与"参与我的业务逻辑的对象"分开。
您通常会得到大量的冗余代码,但它确实实现了对现有对象零更改的目标。
可以使用
例如:
1 2 3 4 5 6 7 8 9 10 | [MetadataType(typeof(MyModelMetadata))] public class MyModel : MyModelBase { ... /* the current model code */ } [DataContract] public class MyModelMetadata { [DataMember] public string Name { get; set; } } |
你可以一直使用DTO。创建一个单独的类,该类包含序列化对象所需的所有内容。然后将您的域模型投影到DTO。您可以使用automapper之类的工具来简化这个过程。
关于绩效
除非每个类有成百上千个对象或大量属性,否则转换DTO和从DTO转换的操作可能没有那么大的性能开销。
如果您使用的是像ef这样的东西,并且没有序列化每个属性,那么您甚至可以通过将ef查询直接投影到DTO来减少一些开销。
这是一个戏剧性的例子,但是我有(设计不好的)数据库模型,每种类型有50多个属性。通过改为只有我关心的10-15属性的DTO,我几乎可以将WCF服务的性能提高一倍。
WCF能够序列化没有属性的对象。这些属性允许定制。例如,这两个类将由
1 2 3 4 5 6 7 8 9 10 11 12 | public class Customer { public string FirstName { get; set; } public string LastName { get; set; } } [DataContract] public class Customer { [DataMember] public string FirstName { get; set; } [DataMember] public string LastName { get; set; } } |
值得一提的是,您确实应该用属性标记您的类。它们不像你想象的那么"杂乱"。它实际上会在将来帮你避免头痛。例如:
1 2 3 4 5 6 7 8 9 | [DataContract(Name ="Customer")] public class Customer { [DataMember(Name ="FirstName")] public string FirstName { get; set; } [DataMember(Name ="LastName")] public string LastName { get; set; } } |
在前面的代码示例中,我显式地设置类和成员的名称。这将允许我在不破坏消费者代码的情况下重构名称。因此,如果有人决定将我的类命名为customerdetail而不是customer,那么我仍然可以将该名称保留为customer,以便我的服务的消费者继续工作。