我正在编写一些修改Windows Server配置的软件(如MS-DNS,IIS,文件系统的一部分)。我的设计有一个服务器进程,用于构建服务器配置状态的内存中对象图和请求此对象图的客户端。然后,服务器将序列化图形,将其发送到客户端(可能使用WCF),然后服务器对此图形进行更改并将其发送回服务器。服务器接收图表并继续对服务器进行修改。
但是我了解到WCF中的对象图序列化并不像我原先想象的那么简单。我的对象具有层次结构,并且许多具有参数化构造函数和不可变属性/字段。还有许多集合,数组和字典。
我对WCF序列化的理解是它需要使用XmlSerializer或DataContractSerializer,但是DCS对我的对象图的设计施加了限制(不可变数据似乎是正确的,它还需要无参数构造函数)。我理解XmlSerializer允许我使用自己的类,只要它们实现ISerializable并具有反序列化构造函数。我很好。
我和我的一个朋友谈过这个问题,他主张采用仅限数据传输对象的路线,在那里我必须维护一个单独的DataContract对象图来传输数据并重新实现我的服务器客户端上的对象。
我的另一位朋友说,因为我的服务只有两个操作(“GetServerConfiguration”和“PutServerConfiguration”),所以完全跳过WCF并实现我自己的使用套接字的服务器可能是值得的。
所以我的问题是:
答案 0 :(得分:3)
对象图可以与DataContract序列化一起使用。
注意:确保您保留对象引用,这样当它们都应该是相同的引用时,您最终不会得到图中同一对象的多个副本,默认情况下行为不会保留这样的身份。
这可以通过在构建DataContractSerializer时指定preserveObjectReferences
参数或为true
上的IsReference属性指定DataContractAttribute
来完成(最后一个属性)需要.NET 3.5SP1 )。
但是,当通过WCF发送对象图时,如果不注意确保图形保持合理的大小,则存在与WCF配额相冲突的风险(并且有很多)。
对于net.tcp
传输,例如,要设置的重要内容包括maxReceivedMessageSize
,maxStringContentLength
和maxArrayLength
。更不用说图形(maxObjectsInGraph
)中允许的65335个不同对象的隐藏配额,只能被忽略。
您还可以使用仅使用DataContractSerializer
公开读取访问器的类,并且没有无参数构造函数:
using System;
using System.IO;
using System.Runtime.Serialization;
class DataContractTest
{
static void Main(string[] args)
{
var serializer = new DataContractSerializer(typeof(NoParameterLessConstructor));
var obj1 = new NoParameterLessConstructor("Name", 1);
var ms = new MemoryStream();
serializer.WriteObject(ms, obj1);
ms.Seek(0, SeekOrigin.Begin);
var obj2 = (NoParameterLessConstructor)serializer.ReadObject(ms);
Console.WriteLine("obj2.Name: {0}", obj2.Name);
Console.WriteLine("obj2.Version: {0}", obj2.Version);
}
[DataContract]
class NoParameterLessConstructor
{
public NoParameterLessConstructor(string name, int version)
{
Name = name;
Version = version;
}
[DataMember]
public string Name { get; private set; }
[DataMember]
public int Version { get; private set; }
}
}
这是有效的,因为DataContractSerializer
可以在不调用构造函数的情况下实例化类型。
答案 1 :(得分:0)
你让自己与序列化器混淆了:
XmlSerializer 需要一个无参数构造函数,因为在反序列化时,.NET运行库将实例化该类型的新对象,然后设置其属性
DataContractSerializer 没有此类要求
查看blog post by Dan Rigsby解释序列化器的所有荣耀并比较两者。
现在为您的设计 - 我的主要问题是:是否有一个函数可以返回所有设置,客户端操作那些,然后另一个函数接收所有信息?
难道你不能将这些东西分解成更小的块,更小的方法调用吗?例如。有单独的服务方法来设置配置的每个单独项目?那样,你可以