none
Expor metódos genericos em WCF RRS feed

  • Pergunta

  • Salve galera !!!

      Estou tentando expor metodos genericos no meu serviço WCF e estou tendo dificuldades com o proposto, tenho uma classe base para todas as minhas entidades :

    public abstract class EntityBase : INotifyPropertyChanged 
      {
       
    
        private static readonly Dictionary<string, PropertyChangedEventArgs> eventArgCache;
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        #region Propriedades
    
        public int Id { get; set; }
    
        #endregion
    
        static EntityBase()
        {
          eventArgCache = new Dictionary<string, PropertyChangedEventArgs>();
        }
    
        protected EntityBase()
        {
        }
    
        protected virtual void AfterPropertyChanged(string propertyName)
        {
        }
    
        public static PropertyChangedEventArgs GetPropertyChangedEventArgs(string propertyName)
        {
          if (String.IsNullOrEmpty(propertyName))
            throw new ArgumentException( "Propriedade não poder se nula ou vazia.");
    
          PropertyChangedEventArgs args;
    
          lock (typeof(EntityBase))
          {
            bool isCached = eventArgCache.ContainsKey(propertyName);
    
            if (!isCached)
            {
              eventArgCache.Add(propertyName, new PropertyChangedEventArgs(propertyName));
            }
    
            args = eventArgCache[propertyName];
          }
    
          return args;
        }
    
        protected void RaisePropertyChanged(string propertyName)
        {
          
          PropertyChangedEventHandler handler = this.PropertyChanged;
    
          if (handler != null)
          {
            
            PropertyChangedEventArgs args = GetPropertyChangedEventArgs(propertyName);
    
            handler(this, args);
          }
    
          this.AfterPropertyChanged(propertyName);
        }
      }

     O meu contrato estou definindo da seguinte maneira :

      [ServiceContract]
      // [ServiceKnownType(typeof(EntityBase))]
      public interface ITableMethods<T> where T : EntityBase 
      {
        
        
        [OperationContract]
        T FindById(int id);
    
        [OperationContract]
        bool Save(T entity);
    
        [OperationContract]
        bool Delete(T entity);
    
        [OperationContract]
        List<T> ListAll();  
        
      }
    

     e o serviço :

    public partial class DbService : ITableMethods<CadPais>
      {
        public CadPais FindById(int id)
        {
          throw new NotImplementedException();
        }
    
        public bool Save(CadPais entity)
        {
          throw new NotImplementedException();
        }
    
        public bool Delete(CadPais entity)
        {
          throw new NotImplementedException();
        }
    
        public List<CadPais> ListAll()
        {
          throw new NotImplementedException();
        }
      }
    


    App.Config :

     <services>
       <service name="WcfService.DbService">
        <endpoint address="" binding="wsHttpBinding" contract="WcfService.IQueryTable{PFInfo.CadPais,Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}" >
         <identity>
          <dns value="localhost" />
         </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
         <baseAddresses>
          <add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfService/DbService/" />
         </baseAddresses>
        </host>
       </service>
      </services>

      ao executar o serviço recebo o seguinte erro :

    System.InvalidOperationException: The contract name 'WcfService.ITableMethods{PFInfo.CadPais,Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}' could not be found in the list of contracts implemented by the service 'DbService'.
      at System.ServiceModel.Description.ConfigLoader.LookupContract(String contractName, String serviceName)
      at System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, Action`1 addBaseAddress)
      at System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, ServiceElement serviceSection)
      at System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, String configurationName)
      at System.ServiceModel.ServiceHostBase.ApplyConfiguration()
      at System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses)
      at System.ServiceModel.ServiceHost.InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses)
      at System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses)
      at Microsoft.Tools.SvcHost.ServiceHostHelper.CreateServiceHost(Type type, ServiceKind kind)
      at Microsoft.Tools.SvcHost.ServiceHostHelper.OpenService(ServiceInfo info)

     alguem teria alguma dica de como resolver isso, desde já agradeço qualquer contribuição

     

    At.

    José Carlos


     
     

    segunda-feira, 20 de junho de 2011 21:02

Respostas

Todas as Respostas

  • Boas José Carlos,

    O nome da interface definido na configuração do endpoint no arquivo de configuração, está diferente daquele que foi realmente implementado no serviço (ITableMethods).
    http://www.israelaece.com
    terça-feira, 21 de junho de 2011 11:51
    Moderador
  • Ola Israel, vc tem sido meu grande guru na caminhada com o WCF, tenho lido muito seus artigos e estudando tb seus videos, eu já corrigi a configuração do endpoint e mesmo assim o erro  persiste

     <service name="WcfService.DbService">
        <endpoint address="" binding="wsHttpBinding" contract="WcfService.ITableMethods{PFInfo.CadPais,Contracts,Version=1.0.0.0, Culture=neutral, PublicKeyToken=null}" >
         <identity>
          <dns value="localhost" />
         </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
         <baseAddresses>
          <add baseAddress="http://localhost:8732/Design_Time_Addresses/WcfService/DbService/" />
         </baseAddresses>
        </host>
       </service>
      </services>
    

      Esse tipo de implementado é realmente possivel no WCF, tenho muitas entidades e como deu pra perceber nos codigos acima todas elas terão metodos como o mesmo proposito, o que irá mudar é apenas o nome da entidade, não gostaria de implementar o código varias vezes para cada entidade, tens alguma dica de como poderia fazer isso.

     

    terça-feira, 21 de junho de 2011 12:36
  • Boas José Carlos,

    Tome cuidado que Generics são características de plataforma, e pode não se comportar da forma como você espera: http://www.israelaece.com/post/Utilizando-Generics-em-Servicos.aspx.

    De qualquer forma, para representar tipos genéricos no arquivo de configuração, você precisa utilizar a seguinte sintaxe:

    <endpoint
        address=""
        binding="wsHttpBinding"
        contract="WcfService.ITableMethods`1[[PFInfo.CadPais, Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" >


    http://www.israelaece.com
    terça-feira, 21 de junho de 2011 14:38
    Moderador
  •  

    Valeu Israel deu certo, obrigado !

     

    José Carlos

    terça-feira, 21 de junho de 2011 19:29