C# 在使用WCF的应用程序中,我应该在哪里放置比较器?

C# 在使用WCF的应用程序中,我应该在哪里放置比较器?,c#,wcf,architecture,service,C#,Wcf,Architecture,Service,我有一个应用程序使用WCF进行所有数据访问。它返回一些业务对象并执行一些操作 此代码应该存在于我的客户机中还是存在于我的服务中?如果在服务中,我应该如何实现它?我可以简单地将其添加为我的业务对象的接口吗?这将通过WCF服务代理代码实现吗 (这是来自MSDN的一个示例,我希望在实现我自己的示例之前获得一些反馈,但99%相同) //产品类的自定义比较器。 类ProductComparer:IEqualityComparer { //如果名称和产品编号相等,则产品相等。 公共布尔等于(乘积x,乘积y)

我有一个应用程序使用WCF进行所有数据访问。它返回一些业务对象并执行一些操作

此代码应该存在于我的客户机中还是存在于我的服务中?如果在服务中,我应该如何实现它?我可以简单地将其添加为我的业务对象的接口吗?这将通过WCF服务代理代码实现吗

(这是来自MSDN的一个示例,我希望在实现我自己的示例之前获得一些反馈,但99%相同)

//产品类的自定义比较器。
类ProductComparer:IEqualityComparer
{
//如果名称和产品编号相等,则产品相等。
公共布尔等于(乘积x,乘积y)
{
//检查比较对象是否引用相同的数据。
if(Object.ReferenceEquals(x,y))返回true;
//检查是否有任何比较对象为空。
if(Object.ReferenceEquals(x,null)| | Object.ReferenceEquals(y,null))
返回false;
//检查产品的属性是否相等。
返回x.Code==y.Code&&x.Name==y.Name;
}
//如果Equals()对一对对象返回true,
//GetHashCode必须为这些对象返回相同的值。
public int GetHashCode(产品)
{
//检查对象是否为空。
if(Object.ReferenceEquals(product,null))返回0;
//如果名称字段不为null,则获取其哈希代码。
int-hashProductName=product.Name==null?0:product.Name.GetHashCode();
//获取代码字段的哈希代码。
int hashProductCode=product.Code.GetHashCode();
//计算产品的哈希代码。
返回hashProductName^hashProductCode;
}
}

请记住,通过WCF(或通过任何基于SOAP的服务)传输的数据仅为消息。它们没有行为(不可互操作),因此您所有的良好行为都将在翻译过程中丢失

这意味着您实际上只有一个选择:您的业务逻辑必须驻留在服务中,因为它不能驻留在客户机上


也就是说,有几种方法可以在服务和客户机之间共享代码,但除非您纯粹将WCF用作通信堆栈,否则不建议使用WCF,因为它将客户机和服务连接在一起,并且几乎不可能独立地改变这两种方式(更不用说让新客户机使用该服务了)。

,WCF生成的代理是部分类,因此即使使用mex生成,也可以在客户端添加行为

您还可以使用程序集共享(在命令行中使用
/reference
,或者选中IDE中的复选框),然后您可以在客户端和服务器上使用完全相同的类型,但它打破了大多数“纯”SOA规则

我想这取决于你感觉有多“纯洁”。纯粹但必须维护两个相似的代码库的痛苦可能会超过程序集共享的方便但肮脏。这取决于应用程序是什么。我已经在很多场合愉快地使用了程序集共享,我没有感到内疚;这是这种情况下最明智的选择


只需记住,客户端代码是一种便利——始终将客户端视为敌方,因此即使您的客户端使用程序集共享,也要记住,敌方客户端可能不会,因此不会遵守您的规则;始终在服务器上进行验证。

这就是我的想法——因此我需要创建一个方法来公开从我的WCF服务中公开的比较器?我的目标是能够在客户端上执行此操作,进行我自己的比较:productsA.Except(productsB)(两者都是IEnumerable)@Nate Bross:我注意到你对Marc Gravell的评论中,你的比较主要是为了展示。如果是这样的话,您应该只在客户端实现该功能,因为它不是一个业务逻辑……您能回答吗?我认为在客户端级别这样做最有意义,因为此比较的最终结果是用于显示目的。
// Custom comparer for the Product class.
class ProductComparer : IEqualityComparer<Product>
{
    // Products are equal if their names and product numbers are equal.
    public bool Equals(Product x, Product y)
    {

        // Check whether the compared objects reference the same data.
        if (Object.ReferenceEquals(x, y)) return true;

        // Check whether any of the compared objects is null.
        if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
            return false;

        // Check whether the products' properties are equal.
        return x.Code == y.Code && x.Name == y.Name;
    }

    // If Equals() returns true for a pair of objects,
    // GetHashCode must return the same value for these objects.

    public int GetHashCode(Product product)
    {
        // Check whether the object is null.
        if (Object.ReferenceEquals(product, null)) return 0;

        // Get the hash code for the Name field if it is not null.
        int hashProductName = product.Name == null ? 0 : product.Name.GetHashCode();

        // Get the hash code for the Code field.
        int hashProductCode = product.Code.GetHashCode();

        // Calculate the hash code for the product.
        return hashProductName ^ hashProductCode;
    }
}