在前面的文章中,我们曾试过用继承的方式来实现版本更新。如果我们直接修改原有服务和数据类型会怎么样呢?
测试原型:
[DataContract]
public class Data
{
[DataMember]
public int x;
}
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Test(Data d);
}
public class Data
{
[DataMember]
public int x;
}
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Test(Data d);
}
客户端代理
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.42
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace ConsoleApplication1.localhost
{
[GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[DataContractAttribute(Namespace = "...")]
[SerializableAttribute()]
public partial class Data : object, IExtensibleDataObject
{
[OptionalFieldAttribute()]
private int xField;
[DataMemberAttribute()]
public int x
{
get
{
return this.xField;
}
set
{
this.xField = value;
}
}
}
[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[ServiceContractAttribute(ConfigurationName = "ConsoleApplication1.localhost.IMyService")]
public interface IMyService
{
[OperationContractAttribute(Action = "http://tempuri.org/IMyService/Test", ReplyAction = "...")]
void Test(Data d);
}
[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IMyServiceChannel : IMyService, IClientChannel
{
}
[DebuggerStepThroughAttribute()]
[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class MyServiceClient : ClientBase<IMyService>, IMyService
{
public void Test(Data d)
{
base.Channel.Test(d);
}
}
}
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.42
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace ConsoleApplication1.localhost
{
[GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[DataContractAttribute(Namespace = "...")]
[SerializableAttribute()]
public partial class Data : object, IExtensibleDataObject
{
[OptionalFieldAttribute()]
private int xField;
[DataMemberAttribute()]
public int x
{
get
{
return this.xField;
}
set
{
this.xField = value;
}
}
}
[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[ServiceContractAttribute(ConfigurationName = "ConsoleApplication1.localhost.IMyService")]
public interface IMyService
{
[OperationContractAttribute(Action = "http://tempuri.org/IMyService/Test", ReplyAction = "...")]
void Test(Data d);
}
[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IMyServiceChannel : IMyService, IClientChannel
{
}
[DebuggerStepThroughAttribute()]
[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class MyServiceClient : ClientBase<IMyService>, IMyService
{
public void Test(Data d)
{
base.Channel.Test(d);
}
}
}
我们将对该服务和数据类型进行升级,添加新的成员和服务方法。
[DataContract]
public class Data
{
[DataMember]
public int x;
[DataMember]
public int y;
}
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Test(Data d);
[OperationContract]
void Test2(int x);
}
public class Data
{
[DataMember]
public int x;
[DataMember]
public int y;
}
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Test(Data d);
[OperationContract]
void Test2(int x);
}
测试结果表明,客户端在不更新代理文件的情况下依然正常执行。看来直接通过修改进行版本更新也没有什么问题。要是我们修改了成员的名称会怎么样?也没问题,不过要使用 Name 属性了。
[DataContract]
public class Data
{
[DataMember(Name="x")]
public int x2;
[DataMember]
public int y;
}
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Test(Data d);
[OperationContract]
void Test2(int x);
}
public class Data
{
[DataMember(Name="x")]
public int x2;
[DataMember]
public int y;
}
[ServiceContract]
public interface IMyService
{
[OperationContract]
void Test(Data d);
[OperationContract]
void Test2(int x);
}
提示:
1. 最好为服务和相关成员特性添加 Namespace / Name 属性。(不要受我的演示代码影响…… )
2. 还是使用继承方式进行版本更新要好些,避免因为意味更改造成原有客户端无法执行。