Como você retornar um tipo definido pelo usuário de um serviço WCF?
-
22-07-2019 - |
Pergunta
Eu tenho um serviço WCF hospedado no IIS. A intenção é que os clientes para fazer uma chamada e receber uma classe personalizada que é definida em outro projeto / dll. I têm gerado um cliente de serviço usando o svcutil.exe. O problema é este cliente gerada automaticamente contém uma nova definição parcial / proxy para a classe Eu estou tentando retornar do serviço. Ele agora lança um erro de conversão entre a minha classe personalizada original e a nova definição parcial em tempo de compilação. Assim como você retornar tipos definidos pelo usuário de um serviço WCF? Conselho apreciado.
Solução
Apenas a segunda Yossi / é rico pensamentos:
- sim, você pode adicionar uma referência para a DLL compartilhada (em vez de usar a classe de proxy gerada)
- sim, derrota um monte da intenção de-contratos de dados, e se qualquer tipo de serialização personalizada está acontecendo, você pode ter problemas se estendem seu serviço
Eu tenho ido por esse caminho antes, e em alguns aspectos desejo que eu não tinha. Re serialização extensibilidade / custom - você tem que ser muito cuidado. Um pouco mais fácil se você usar um serializador pré-rolou, como protobuf-net ( que pode integrar diretamente em WCF, e que é projetado com extensibilidade em mente), mas não é fácil.
Na verdade, um vantagem de compartilhar as classes é que o torna um pouco mais fácil de teste: uma vez que você tem o mesmo IFoo
em todos os lugares, você pode zombar que IFoo
com chance razoável de sucesso. É mais difícil para zombar quando o proxy se envolve (como você mudar as peças mais se deslocam entre o código de teste eo código de produção).
Outras dicas
Se o tipo que você deseja retornar de sua chamada de serviço não está marcado como um DataContract
então você não será capaz de devolvê-lo a partir WCF sem fornecer uma cópia desse mesmo conjunto para o seu aplicativo cliente.
using System;
using System.ServiceModel;
[ServiceContract]
interface IService
{
[OperationContract]
TimeSpan GetTimeSpan();
}
class Service : IService
{
public TimeSpan GetTimeSpan() { return DateTime.Now.TimeOfDay; }
}
Por que faz o trabalho de código anterior, então? Ele funciona porque ambos os lados da chamada de serviço têm System.dll
para que ambos saber sobre o tipo System.TimeSpan
que é o tipo de retorno da GetTimeSpan()
OperationContract.
Aqui está um exemplo usando um DataContract
:
using System;
using System.ServiceModel;
using System.Runtime.Serialization;
[ServiceContract]
interface IService
{
[OperationContract]
Contract GetContract();
}
[DataContract]
class Contract
{
[DataMember]
public String MyProperty { get; set; }
}
class Service : IService
{
public Contract GetContract() { return new Contract(); }
}
atributos Agora você forneceu serialização de uma classe que você definiu (Contract
) - o que irá permitir que você use svcutil.exe
para criar classes de proxy em seu aplicativo cliente que será serializada e enviada para o serviço WCF
Agora, se você quiser retornar um tipo que não é um DataContract
você deve fornecer uma cópia do assembly que contém esse tipo para o seu aplicativo cliente.
Uma das coisas que precisam acontecer é que o usuário deve configurar o serviço de referência para usar seus tipos do DLL em vez da classe definida pelo proxy - http://msdn.microsoft.com/en-us/library/bb628653.aspx
Nós andamos por esse caminho no passado, e na verdade o problema é que, é claro, estes são duas classes diferentes, assim você terá que seguir o link fornecido pelo @ Rich Reuter;
Temos, porém, aprendi da maneira mais difícil por que isso é uma prática ruim como ele vai Agains o terceiro princípio de "esquema compartilhar serviços e do contrato, não a classe" SOA.
Claro que o problema não é apenas não seguir um conjunto "regra" por alguém, em algum momento, mas que havia grandes razões para isso a ser sugerido - nós aprendemos que o preço de tal acoplamento forte entre o serviço ea significa que o cliente é muito difícil para liberar ou - se o serviço precisa adicionar outro campo para essa classe, para atender outro cliente - o primeiro cliente pode ser afetada; se o serviço que precisa mudar algo em que definição de classe (ao serviço de outro cliente) - o primeiro cliente voltará a ser afetado, e vice-versa - o cliente pode afetar o ciclo de vida do serviço.
Em grandes projetos este rapidamente se torna um fardo de manutenção enorme.