我之前在序列化不可变类型时遇到了类似的问题,最后我决定实现 ISerialized 接口并使用 SerializationInfo 在序列化/反序列化过程的两端存储和检索私有变量:
http://theburningmonk.com/2010/04/net-tips-making-a-serialized-immutable-struct/ http://theburningmonk.com/2010/04/net-tips-making-a-serializable-immutable-struct/
我刚刚使用相同的技术构建并运行了一个测试应用程序,它似乎对我有用。因此,就您的诊所课程的更改而言,您可以将其更改为:
[Serializable]
public class Clinic : ISerializable
{
public Clinic(string name, string id)
{
Name = name;
Id = id;
}
public Clinic(SerializationInfo info, StreamingContext context)
{
Name= info.GetString("Name");
Id= info.GetString("Id");
}
public string Name{get; private set;}
public string Id{get; private set;}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("Name", Name);
info.AddValue("Id", Id);
}
}
这将解决您从 WCF 传回数据的问题。但从设计的角度来看,我同意 Ladislav 的说法,通常您会希望将域对象与纯粹用于消息传递的对象(DataTransferObjects)分开,在这种情况下,这里是您可能如何处理它的示例:
// the domain object (NOT EXPOSED through the WCF service)
public class Clinic
{
public Clinic(string name, string id)
{
Name = name;
Id = id;
}
public string Name{ get; private set;}
public string Id{ get; private set;}
// other methods encapsulating some business logic, etc.
...
}
// the corresponding DTO object for the domain object Clinic
// this is the type exposed through the WCF layer, that the client knows about
[DataContract]
public class ClinicDTO
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Id { get; set; }
}
// WCF service contract, NOTE it returns ClinicDTO instead of Clinic
[ServiceContract]
public interface IClinicService
{
[OperationContract]
ClinicDTO GetClinicById(string id);
}
为了减轻从 Clinic 转换为 ClinicDTO 的痛苦,您可以在 Clinic 上添加一个方法来执行此操作,或者实现一个隐式/显式转换器。我在这里有一个关于如何执行此操作的示例:http://theburningmonk.com/2010/02/controlling-type-conversion-in-c/ http://theburningmonk.com/2010/02/controlling-type-conversion-in-c/
希望这可以帮助!