使用修饰过的WCF实体类而不引用服务本身

本文关键字:引用 服务 实体 WCF | 更新日期: 2023-09-27 18:03:28

我有一个服务,它产生了一个类,我们说MyProject.Proxy中的OperationDesc。我想让我的类,包含OperationDesc的一些属性。因此,我在MyProject.Entity中创建了一个类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库,我不想做什么。你能建议任何模式或方法,我需要在这里使用?主要目标是用一些额外的属性来装饰服务类,而不引用Proxy库。我可以将所有属性从OperationDesc复制到OperationView并使用AutoMapper,但它看起来像反模式。Thx .

使用修饰过的WCF实体类而不引用服务本身

当您使用面向服务的体系结构时,假定服务器和客户机是完全不同的应用程序。因此,客户端不应该有任何关于你的服务实现的信息,包括你用c#创建的模型类。客户端可能是JavaScript或JAVA/Android或RoR应用程序。因此,c#创建的模型(类)在客户端是完全不可用的。对于客户端,重要的是您定义的协议。因此,假设您在服务器端(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类和

)
public class OperationView : OperationDesc {
    public string DateString {
        get 
        {
            return Created.ToString();
        }
    }    
}

,因为您试图对服务器端实体执行此操作。但这一次,OperationDesc不是服务器应用程序中的类,而是客户端应用程序中的全新类。

所以,不,在客户端创建一个类并复制所有属性并使用AutoMapper根本不是反模式的。

但是:

如果你真的不关心SOA,你只是想避免重复,你可以创建一个类库项目,把你所有的模型放在那里(只是模型),并在所有项目中共享这个库(包括服务和web客户端)。我当然不建议。