WCF具有接口和通用模​​型

时间:2016-02-11 11:34:46

标签: c# wcf generics interface

关于WCF中的接口和泛型有很多关于SO的问题,但我找不到一个与我有相同问题的问题。

我有一份合同服务:

[ServiceContract]
[ServiceKnownType(typeof(CollectionWrapper<IAssociation>))]
public interface IService : 
{
    [OperationContract]
    ICollectionWrapper<IAssociation> FindAssociation(string name, int pageSize, int page);
}

public interface ICollectionWrapper<TModel>
{
    int TotalCount { get; set; }
    IEnumerable<TModel> Items { get; set; }
}

[KnownType(typeof(OrganizationDto))]
[KnownType(typeof(CompanyDto))]
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
    [DataMember]
    public int TotalCount { get; set; }
    [DataMember]
    public IEnumerable<TModel> Items { get; set; }
}

public class CompanyDto :  IAssociation
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class OrganizationDto :  IAssociation
{
    public int Id { get; set; }
    public string Name { get; set; }
}

它与ChannelFactory<IService>一起使用,上面的代码效果很好。但现在我想为服务添加另一个方法,该方法也返回ICollectionWrapper<T>

[OperationContract]
ICollectionWrapper<ICustomer> Search(ISearchQuery searchQuery);

所以我像对待其他人一样注册它:

[ServiceContract]
[ServiceKnownType(typeof(CollectionWrapper<IAssociation>))]
[ServiceKnownType(typeof(CollectionWrapper<ICustomer>))] // This line creates the error.
public interface IService : 
{
    [OperationContract]
    ICollectionWrapper<IAssociation> FindAssociation(string name, int pageSize, int page);

    [OperationContract] // New method.
    ICollectionWrapper<ICustomer> Search(ISearchQuery searchQuery);
}

[KnownType(typeof(OrganizationDto))]
[KnownType(typeof(CompanyDto))]
[KnownType(typeof(CustomerDto))] // New model.
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
    [DataMember]
    public int TotalCount { get; set; }
    [DataMember]
    public IEnumerable<TModel> Items { get; set; }
}

只要我有两个ServiceKnownTypes CollectionWrapper,服务就会失败并出现以下错误:

  

基础连接已关闭:发生意外错误   收到。

内在的例外:

  

远程主机强行关闭现有连接。

我可以在这两行代码之间切换(删除一行,然后添加另一行):

[ServiceKnownType(typeof(CollectionWrapper<ICustomer>))]

[ServiceKnownType(typeof(CollectionWrapper<IAssociation>))]

然后每个方法都有效,但从不同时。知道如何让它工作吗?我不想使用具体的课程。

这是我尝试过的(并且失败了):

[ServiceKnownType(typeof(CollectionWrapper<object>))]

[ServiceKnownType(typeof(CollectionWrapper<>))]

我还尝试为IAssociation和ICustomer分配一个公共接口,但它也不起作用。

[ServiceKnownType(typeof(CollectionWrapper<ISomething>))]

它适用于IEnumerable<T>IList<T>,但不适用于ICollectionWrapper<T>

修改

ICustomerIAssociation(和他们的实现)没有任何共同之处。他们不会从彼此继承任何东西,也没有任何其他共同的依赖。

2 个答案:

答案 0 :(得分:1)

[OperationContract]
ICollectionWrapper<ICustomer> Search(ISearchQuery searchQuery);

服务如何知道ISearchQuery参数存在哪些已知类型?

我认为您需要将[KnownType(typeof(SearchQuery))](或任何调用的ISearchQuery实现)添加到服务定义中。

答案 1 :(得分:1)

经过大量的研究后,我无法找到一个好的解决方案,但我想我会发布我最终得到的解决方案(即使它没有按我想要的方式解决)

[ServiceContract]
[ServiceKnownType(typeof(CompanyDto>))]
[ServiceKnownType(typeof(CompanyDto>))]
[ServiceKnownType(typeof(CustomerDto))]
[ServiceKnownType(typeof(OrganizationDto))]
public interface IService : 
{
    [OperationContract] // Concrete type
    CollectionWrapper<IAssociation> FindAssociation(string name, int pageSize, int page);

    [OperationContract] // Concrete type
    CollectionWrapper<ICustomer> Search(ISearchQuery searchQuery);
}

通过使用具体类而不是接口来解决它。这不是我真正想要的,但现在它解决了我的问题。

这里可能重复:

Generic return types with interface type params in WCF