public static System.Web.Services.Protocols.SoapHttpClientProtocol ClientProxyFactory(
            Parametro oParam,
            TServico TipoServico)
        {
            String ClassName = "";

            try
            {
                string nomeClasse = string.Empty;
                //buscar nome do metodo pelo tServico
                foreach (ClasseServico atr in TipoServico.GetType().GetField(TipoServico.ToString()).GetCustomAttributes(typeof(ClasseServico), false))
                {
                    if (String.IsNullOrEmpty(atr.value))
                    {
                        throw new Exception("Serviço não esta associado com nenhuma classe cliente.");
                    }
                    nomeClasse = atr.value;
                }

                //particularidades
                if (oParam.UF == TCodUfIBGE.Bahia && oParam.tipoEmissao == TNFeInfNFeIdeTpEmis.Normal)//Bahia
                {
                    if (TipoServico == TServico.Status && oParam.versao == VersaoXML.NFe_v310)
                    {
                        nomeClasse = "NfeStatusServico";
                    }

                    if (TipoServico == TServico.Consulta && oParam.versao == VersaoXML.NFe_v310)
                    {
                        nomeClasse = "NfeConsulta";
                    }

                    if (TipoServico == TServico.Inutilizacao && oParam.versao == VersaoXML.NFe_v310)
                    {
                        nomeClasse = "NfeInutilizacao";
                    }
                }

                ClassName =
                    "RDI.NFe2.Business."
                    + GetAmbWebService(oParam, TipoServico) + "."
                    + TipoServico.ToString() + ".";

                String headerClassName = ClassName + "nfeCabecMsg";
                ClassName += nomeClasse;

                Type classType = GetMyAssembly().GetType(ClassName);

                if (classType == null)
                {
                    throw new Exception("Não foi possível definir o tipo do cliente de webservice. #ClientProxyFactory");
                }

                System.Web.Services.Protocols.SoapHttpClientProtocol oServico =
                    (System.Web.Services.Protocols.SoapHttpClientProtocol)System.Activator.CreateInstance(classType);

                if (TipoServico != TServico.ConsultaDFe) //ConsultaDFe não tem header
                {
                    #region Instancia cabecalho

                    Type headerClassType = GetMyAssembly().GetType(headerClassName);

                    if (headerClassType == null)
                    {
                        throw new Exception("Não foi possível definir o tipo do header do cliente de webservice. #ClientProxyFactory");
                    }

                    System.Web.Services.Protocols.SoapHeader oCabecalho =
                        (System.Web.Services.Protocols.SoapHeader)System.Activator.CreateInstance(headerClassType);


                    if ((TipoServico == TServico.ManifestacaoDestinatario) || //ManifestacaoDestinatario deverá usar AN 91
                        (TipoServico == TServico.DownloadNF))                 //DownloadNF deverá usar AN 91
                    {
                        oCabecalho.GetType().GetProperty("cUF").SetValue(oCabecalho, "91", null);
                    }
                    else
                    {
                        oCabecalho.GetType().GetProperty("cUF").SetValue(oCabecalho,
                                                                         ((System.Xml.Serialization.XmlEnumAttribute)oParam.UF.GetType().GetField(
                                                                              oParam.UF.ToString()).GetCustomAttributes(
                                                                              typeof(System.Xml.Serialization.XmlEnumAttribute), false)[0]).Name,
                                                                         null);
                    }
                    string versao = oParam.versaoDados;

                    //particularidade para ConsSitNFe usando v200
                    if (TipoServico == TServico.Consulta && oParam.versao == VersaoXML.NFe_v200)
                    {
                        versao = "2.01";
                    }

                    //Particularidade para RecepcaoEvento
                    if (TipoServico == TServico.RecepcaoEvento)
                    {
                        versao = oParam.versaoDadosEventos;
                    }

                    //particularidade para consultaCadastro
                    if (TipoServico == TServico.Cadastro)
                    {
                        versao = "2.00";
                    }

                    //particularidade para manifestacao destinatario
                    if (TipoServico == TServico.ManifestacaoDestinatario || TipoServico == TServico.DownloadNF)
                    {
                        versao = "1.00";
                    }

                    oCabecalho.GetType().GetProperty("versaoDados").SetValue(oCabecalho, versao, null);
                    oServico.GetType().GetProperty("nfeCabecMsgValue").SetValue(oServico, oCabecalho, null);
                    #endregion
                }
                return(oServico);
            }
            catch (Exception ex)
            {
                throw new Exception("ClientProxyFactory # não foi possível criar o cliente (" + ClassName + ") para acesso aos webservices da SEFAZ. InnerException: " + ex.Message);
            }
        }
        private static string GetAmbWebService(Parametro oParam, TServico tipoServico)
        {
            String ambiente = string.Empty;

            if (oParam.conexao == TipoConexao.NFCe)
            {
                //oParam.NFCe [HNC|PNC].[AtendidoPor].***
                if (oParam.tipoAmbiente == TAmb.Homologacao)
                {
                    ambiente = "HNC.";
                }
                else if (oParam.tipoAmbiente == TAmb.Producao)
                {
                    ambiente = "PNC.";
                }
                else
                {
                    throw new Exception("Tipo de Ambiente não definido.");
                }
            }
            else if (oParam.conexao == TipoConexao.GNRE)
            {
                //oParam.NFCe [HNC|PNC].[AtendidoPor].***
                if (oParam.tipoAmbiente == TAmb.Homologacao)
                {
                    ambiente = "HWG.";
                }
                else if (oParam.tipoAmbiente == TAmb.Producao)
                {
                    ambiente = "PWG.";
                }
                else
                {
                    throw new Exception("Tipo de Ambiente não definido.");
                }
            }
            else
            {
                if ((tipoServico == TServico.Autorizacao || tipoServico == TServico.RetAutorizacao) && oParam.versao != VersaoXML.NFe_v310)
                {
                    throw new ArgumentException("V200 não possui Webservice de " + tipoServico.ToString());
                }


                // HNF|PNF :  são utilizados pelos novos servicos de todas as UFs e por todos os servicos de SP e PR
                // os demais servicos utilizam [HWS|PWS]
                if ((tipoServico != TServico.Cadastro) &&                 //Cadastro deverá usar PWS|HWS
                    (tipoServico != TServico.ConsultaDFe) &&              //ConsultaDFe deverá usar PWS|HWS
                    (tipoServico != TServico.DownloadNF) &&               //DownloadNF deverá usar PWS|HWS
                    (tipoServico != TServico.ManifestacaoDestinatario) && //ManifestacaoDestinatario deverá usar PWS|HWS
                    (tipoServico == TServico.Autorizacao || tipoServico == TServico.RetAutorizacao
                     //particularidades
                     || (oParam.UF == TCodUfIBGE.RioGrandedoSul) || //atualizado somente com os WS da versão 3.1 //25/05/2015
                     (oParam.UF == TCodUfIBGE.SaoPaulo && oParam.versao == VersaoXML.NFe_v310) ||
                     (oParam.UF == TCodUfIBGE.Parana && oParam.versao == VersaoXML.NFe_v310) ||
                     (oParam.UF == TCodUfIBGE.Bahia && oParam.versao == VersaoXML.NFe_v310 && tipoServico != TServico.RecepcaoEvento)))
                {
                    //[HNF|PNF].
                    if (oParam.tipoAmbiente == TAmb.Homologacao)
                    {
                        ambiente = "HNF.";
                    }
                    else if (oParam.tipoAmbiente == TAmb.Producao)
                    {
                        ambiente = "PNF.";
                    }
                    else
                    {
                        throw new Exception("Tipo de Ambiente não definido.");
                    }
                }
                else
                {
                    //[HWS|PWS].
                    if (oParam.tipoAmbiente == TAmb.Homologacao)
                    {
                        ambiente = "HWS.";
                    }
                    else if (oParam.tipoAmbiente == TAmb.Producao)
                    {
                        ambiente = "PWS.";
                    }
                    else
                    {
                        throw new Exception("Tipo de Ambiente não definido.");
                    }
                }
            }

            //Verificar de acordo com a UF e determinar qual webservice atende.
            if (oParam.tipoEmissao == TNFeInfNFeIdeTpEmis.ContingenciaSVCAN ||
                oParam.tipoEmissao == TNFeInfNFeIdeTpEmis.ContingenciaSVCRS)
            {
                //[SVC_AtendidoPor]oParam.UF.GetType().GetField(oParam.UF.ToString()).GetCustomAttributes(typeof(
                foreach (SVC_AtendidoPor atr in
                         oParam.UF.GetType().GetField(oParam.UF.ToString()).GetCustomAttributes(typeof(SVC_AtendidoPor), false))
                {
                    if (String.IsNullOrEmpty(atr.value))
                    {
                        throw new Exception("UF não esta sendo atendida por nenhum WebService do SVC.");
                    }

                    ambiente += atr.value;
                }
            }
            else if (oParam.tipoEmissao == TNFeInfNFeIdeTpEmis.ContigenciaSCAN)
            {
                ambiente += "SCAN";
            }
            else
            {
                //particularidade
                if (tipoServico == TServico.Cadastro && oParam.UF == TCodUfIBGE.EspiritoSanto)
                {
                    ambiente += "ES";
                }
                else if (tipoServico == TServico.ManifestacaoDestinatario || tipoServico == TServico.ConsultaDFe || tipoServico == TServico.DownloadNF)
                {
                    ambiente += "AN";
                }
                else
                {
                    if (oParam.conexao == TipoConexao.NFCe)
                    {
                        foreach (NFCe_AtendidoPor atr in oParam.UF.GetType().GetField(oParam.UF.ToString()).GetCustomAttributes(typeof(NFCe_AtendidoPor), false))
                        {
                            if (String.IsNullOrEmpty(atr.value))
                            {
                                throw new Exception("UF não esta sendo atendida por nenhum WebService.");
                            }

                            ambiente += atr.value;
                        }
                    }
                    else if (oParam.conexao == TipoConexao.NFCe)
                    {
                        ambiente += "GNRE";
                    }
                    else
                    {
                        foreach (NFe_AtendidoPor atr in oParam.UF.GetType().GetField(oParam.UF.ToString()).GetCustomAttributes(typeof(NFe_AtendidoPor), false))
                        {
                            if (String.IsNullOrEmpty(atr.value))
                            {
                                throw new Exception("UF não esta sendo atendida por nenhum WebService.");
                            }

                            ambiente += atr.value;
                        }
                    }
                }
            }
            return(ambiente);
        }