在不引用服务本身的情况下使用修饰的 WCF 实体 class
Use decorated WCF entity class without referencing service itself
我有一个服务,它产生了 class,比方说 OperationDesc
在 MyProject.Proxy
中。我想要我的 class,它包含 OperationDesc
的一些属性。所以我在 MyProject.Entity
中创建了一个 class OperationView
并从 OperationDesc
.
派生了它
namespace MyProject.Proxy {
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
}
}
namespace MyProject.Entity {
using Proxy;
public class OperationView : OperationDesc {
public string DateString {
get
{
return Created.ToString();
}
}
}
}
namespace MyProject.Web {
using Entity;
public class HomeController : Controller {
public ActionResult(){
var operation = ... logic ...;
operation.Id <--- require Proxy reference
}
}
}
现在我尝试在 MyProject.Web
中使用 OperationView
,并参考 MyProject.Entity
。但是我无法访问 OperationDesc
属性,除非我引用 Proxy
库,这是我不想做的。 你能建议我在这里需要使用的任何模式或方法吗? 主要目标是用一些额外的属性装饰服务 class,而不引用 Proxy
库。 Ofc 我可以将所有属性从 OperationDesc
复制到 OperationView
并使用 AutoMapper,但它看起来像反模式。谢谢
当您使用面向服务的体系结构时,假定服务器和客户端是完全不同的应用程序。因此,客户端不应该有关于您的服务实现的任何信息,包括您使用 c# 创建的模型 classes。客户端可能是 JavaScript 或 JAVA/Android 或 RoR 应用程序。因此,C# 创建的模型(classes)在客户端完全不可用。对于客户来说,重要的是您定义的协议。所以,假设你在服务器端(wcf 项目)有这个模型:
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
}
客户需要知道的是这样的:
type OperationDesc {
Id (Int64),
Created (DateTime)
}
仅此而已。所以每个客户端都可能有自己的模型实现:
JavaScript:
function OperationDesc(){
this.Id = 0;
this.Created = new Date(); // or null or anything else
}
JAVA:
public class OperationDesc {
private Long id;
private Date created;
public void setId(Long value) { this.id = value; }
public Long getId() { return this.id; }
public void setCreated(Date value) { this.created= value; }
public Date getCreated() { return this.created; }
}
C#:
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
}
现在,您已经定义了您的协议,您可以看到任何类型的客户端应用程序,都可以与您的服务进行通信。那么,在您的特定应用程序中,您需要额外的 属性 吗?好的,没问题:
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
public string DateString {
get
{
return Created.ToString();
}
}
}
(或者您可以创建一个纯 OperationDesc
class 和一个
public class OperationView : OperationDesc {
public string DateString {
get
{
return Created.ToString();
}
}
}
正如您尝试对服务器端实体所做的那样。但是这一次,OperationDesc
不是服务器应用程序中的 class,而是客户端应用程序中的全新 class。
所以,不,在客户端创建 class 并复制所有属性并使用 AutoMapper 根本不是反模式。
但是:
如果您真的不关心 SOA 而只是想避免重复,您可以创建一个 class-library 项目并将所有模型放在那里(只是模型)并共享该库项目(包括服务和网络客户端)。我当然不建议这样做。
我有一个服务,它产生了 class,比方说 OperationDesc
在 MyProject.Proxy
中。我想要我的 class,它包含 OperationDesc
的一些属性。所以我在 MyProject.Entity
中创建了一个 class OperationView
并从 OperationDesc
.
namespace MyProject.Proxy {
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
}
}
namespace MyProject.Entity {
using Proxy;
public class OperationView : OperationDesc {
public string DateString {
get
{
return Created.ToString();
}
}
}
}
namespace MyProject.Web {
using Entity;
public class HomeController : Controller {
public ActionResult(){
var operation = ... logic ...;
operation.Id <--- require Proxy reference
}
}
}
现在我尝试在 MyProject.Web
中使用 OperationView
,并参考 MyProject.Entity
。但是我无法访问 OperationDesc
属性,除非我引用 Proxy
库,这是我不想做的。 你能建议我在这里需要使用的任何模式或方法吗? 主要目标是用一些额外的属性装饰服务 class,而不引用 Proxy
库。 Ofc 我可以将所有属性从 OperationDesc
复制到 OperationView
并使用 AutoMapper,但它看起来像反模式。谢谢
当您使用面向服务的体系结构时,假定服务器和客户端是完全不同的应用程序。因此,客户端不应该有关于您的服务实现的任何信息,包括您使用 c# 创建的模型 classes。客户端可能是 JavaScript 或 JAVA/Android 或 RoR 应用程序。因此,C# 创建的模型(classes)在客户端完全不可用。对于客户来说,重要的是您定义的协议。所以,假设你在服务器端(wcf 项目)有这个模型:
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
}
客户需要知道的是这样的:
type OperationDesc {
Id (Int64),
Created (DateTime)
}
仅此而已。所以每个客户端都可能有自己的模型实现:
JavaScript:
function OperationDesc(){
this.Id = 0;
this.Created = new Date(); // or null or anything else
}
JAVA:
public class OperationDesc {
private Long id;
private Date created;
public void setId(Long value) { this.id = value; }
public Long getId() { return this.id; }
public void setCreated(Date value) { this.created= value; }
public Date getCreated() { return this.created; }
}
C#:
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
}
现在,您已经定义了您的协议,您可以看到任何类型的客户端应用程序,都可以与您的服务进行通信。那么,在您的特定应用程序中,您需要额外的 属性 吗?好的,没问题:
public class OperationDesc {
public long Id { get; set; }
public DateTime Created { get; set; }
public string DateString {
get
{
return Created.ToString();
}
}
}
(或者您可以创建一个纯 OperationDesc
class 和一个
public class OperationView : OperationDesc {
public string DateString {
get
{
return Created.ToString();
}
}
}
正如您尝试对服务器端实体所做的那样。但是这一次,OperationDesc
不是服务器应用程序中的 class,而是客户端应用程序中的全新 class。
所以,不,在客户端创建 class 并复制所有属性并使用 AutoMapper 根本不是反模式。
但是:
如果您真的不关心 SOA 而只是想避免重复,您可以创建一个 class-library 项目并将所有模型放在那里(只是模型)并共享该库项目(包括服务和网络客户端)。我当然不建议这样做。