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

标签 c# design-patterns decorator

我有一个服务,它产生了一个类,比如说 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 库。 Ofc 我可以将所有属性从 OperationDesc 复制到 OperationView 并使用 AutoMapper,但它看起来像反模式。谢谢。

最佳答案

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

现在,您已经定义了您的协议(protocol)​​,您可以看到任何类型的客户端应用程序,都可以与您的服务进行通信。那么,在您的特定应用程序中,您需要一个额外的属性吗?好的,没问题:

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 而只是想避免重复,您可以创建一个类库项目并将所有模型放在那里(仅模型)并在所有项目(包括服务和网络)中共享该库-客户)。我当然不建议这样做。

关于c# - 使用修饰的 WCF 实体类而不引用服务本身,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39095180/

相关文章:

c# - 在 C# 中修改集合的模式是什么

c# - 使用设计模式在Visual Studio GUI应用程序中分离 View

django登录后返回上一页

c# - Generic.xaml - 引用样式

c# - 为什么线性探测仅适用于相对主要的步骤?

C# 和从另一个进程读取声音?

属性辅助方法的 c# 泛型

返回不同类型的 JavaScript 函数(Array 与 NodeList)

php - div 中的 Zend 表单元素

带有装饰器和 session 的 django 类 View