How does the Type.Invokemember method work?

Asked

Viewed 574 times

5

I came across this method in a code and was curious how it works because I’ve seen some applications running in C# that use this method, and when searching for the method in Google, I found no clear explanation.

tipoServico.InvokeMember("SalvarXmlRetornoEm", System.Reflection.BindingFlags.SetProperty, null, xml, new object[] { repositorio.xmlRetorno });

This is an example of a code that I saw that it works all right but I have no idea how it works.

 private void EnviarArquivo(Empresa empresa, string arquivoXmlEnvio, string localSalvarXmlRetorno, Object nfe, string metodo)
    {
        //Definir o tipo do serviço
        Type tipoServico = nfe.GetType();

        //Definir o arquivo XML para a classe UniNfeClass
        tipoServico.InvokeMember("NomeArquivoXML", System.Reflection.BindingFlags.SetProperty, null, nfe, new object[] { arquivoXmlEnvio });
        tipoServico.InvokeMember("SalvarXmlRetornoEm", System.Reflection.BindingFlags.SetProperty, null, nfe, new object[] { localSalvarXmlRetorno });
        tipoServico.InvokeMember(metodo, System.Reflection.BindingFlags.InvokeMethod, null, nfe, new[] { empresa });
    }

So the Nfe object is this one:

public class TaskConsultarNfsePorRps : TaskAbst
{
    public override void Execute(Empresa empresa)
    {
        //Definir o serviço que será executado para a classe
        Servico = Servicos.ConsultarNfsePorRps;

        //Ler o XML para pegar parâmetros de envio
        LerXML ler = new LerXML();
        ler.PedSitNfseRps(NomeArquivoXML, empresa);

        //Criar objetos das classes dos serviços dos webservices do SEFAZ
        WebServiceProxy wsProxy = null;
        object pedLoteRps = null;
        string cabecMsg = "";
        PadroesNFSe padraoNFSe = Functions.PadraoNFSe(ler.oDadosPedSitNfseRps.cMunicipio);
        switch (padraoNFSe)
        {
            case PadroesNFSe.GINFES:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                cabecMsg = "<ns2:cabecalho versao=\"3\" xmlns:ns2=\"http://www.ginfes.com.br/cabecalho_v03.xsd\"><versaoDados>3</versaoDados></ns2:cabecalho>";
                break;

            case PadroesNFSe.BETHA:
                wsProxy = new WebServiceProxy(empresa.X509Certificado);
                wsProxy.Betha = new Betha();
                break;

            case PadroesNFSe.THEMA:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.CANOAS_RS:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                cabecMsg = "<cabecalho versao=\"201001\"><versaoDados>V2010</versaoDados></cabecalho>";
                break;

            case PadroesNFSe.ISSNET:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.ISSONLINE:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.BLUMENAU_SC:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.BHISS:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                cabecMsg = "<cabecalho xmlns=\"http://www.abrasf.org.br/nfse.xsd\" versao=\"1.00\"><versaoDados >1.00</versaoDados ></cabecalho>";
                break;

            case PadroesNFSe.GIF:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.DUETO:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis, padraoNFSe);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.WEBISS:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis, padraoNFSe);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                cabecMsg = "<cabecalho xmlns=\"http://www.abrasf.org.br/nfse.xsd\" versao=\"1.00\"><versaoDados >1.00</versaoDados ></cabecalho>";
                break;

            case PadroesNFSe.PAULISTANA:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.SALVADOR_BA:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis, padraoNFSe);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            case PadroesNFSe.PORTOVELHENSE:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis, padraoNFSe);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                cabecMsg = "<cabecalho versao=\"2.00\" xmlns:ns2=\"http://www.w3.org/2000/09/xmldsig#\" xmlns=\"http://www.abrasf.org.br/nfse.xsd\"><versaoDados>2.00</versaoDados></cabecalho>";
                break;

            case PadroesNFSe.PRONIN:
                wsProxy = ConfiguracaoApp.DefinirWS(Servico, empresa, ler.oDadosPedSitNfseRps.cMunicipio, ler.oDadosPedSitNfseRps.tpAmb, ler.oDadosPedSitNfseRps.tpEmis, padraoNFSe);
                pedLoteRps = wsProxy.CriarObjeto(NomeClasseWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio));
                break;

            default:
                throw new Exception("Não foi possível detectar o padrão da NFS-e.");
        }

        if (padraoNFSe != PadroesNFSe.IPM)
        {
            //Assinar o XML
            AssinaturaDigital ad = new AssinaturaDigital();
            ad.Assinar(NomeArquivoXML, empresa, Convert.ToInt32(ler.oDadosPedSitNfseRps.cMunicipio));

            //Invocar o método que envia o XML para o SEFAZ
            oInvocarObj.InvocarNFSe(wsProxy, pedLoteRps, NomeMetodoWS(Servico, ler.oDadosPedSitNfseRps.cMunicipio, empresa.tpAmb), cabecMsg, this, "-ped-sitnfserps", "-sitnfserps", padraoNFSe, Servico, empresa);
        }
    }
}
  • 1

    It would help if the question were clear on what you want to know, what you want to do with it. You could quote where you saw it, what you didn’t understand, post an example of use you can’t use, if you want to make it work internally, or something else. The documentation is here: https://msdn.microsoft.com/en-us/library/66btctbe(v=vs.110). aspx.

  • is that actually I wanted to know exactly this, where I can use this method, I read this documentation and it was not so clear to me, so I would like to learn where I can apply it, what it is useful and helps...

  • 1

    It’s just hard to talk about something so abstractly, without a focus. This is used for reflection https://answall.com/q/13089/101. If you do not need reflection, you do not need this method. If you want to see an example of use: https://answall.com/q/137542/101. It’s complicated? It is. That’s why you need to let us know what you want.

  • This example has already helped, but even if we know more details about what comes in nfe can answer better. I have a larger impression that this code is the gambit of someone who does not know what they are doing. But I can only state in more detail what this method is called. Apparently more people do not know well about it since I took negative. I ended up negatively the response of the gypsy because she is wrong, just read my answer to see the constant mistakes there. He even ended up erasing his, pity that did not withdraw the negative of my reply.

  • I added what’s in the question

  • I improved the answer with what you just added. I was really right, you don’t need this whole complication.

Show 1 more comment

1 answer

3


I strongly advise reading the documentation which has all the details about the method and examples of use.

This is a method belonging to the type Type which is a type basically used for the reflection. This is the kind that gives you all the necessary information about the application types. It makes everything available, as if it were a set of arrays of all the information that’s inside of him. It shows in addition to the type name, the inherited types, its attributes and other general information, all its members, be they variables, properties, methods, etc. You can see all information that is available on the methods.

Methods can be called, right? If you take all the methods or estates (property information) type can call them without even knowing the structure of what is working, you can call something you don’t even know what it is yet while coding.

#Your example

It seems to me that this code is catching a guy (tipoServico) which was created dynamically at runtime (later I find out that it doesn’t), that is, your code doesn’t even know what it is, and it looks like it came from an XML that will define its structure. Probably this type will be defined like this:

var tipoServico = xml.GetType();

I guess I couldn’t use the typeof (confirmed later) because to use it would need to have the information at compile time, which would lose the sense of using the InvokeMember(). I just can’t say because I don’t have more information on the question.

It is known that there is a property called SalvarXmlRetornoEm and he will use the method of property that makes the set.

Since every property can only be applied to an object, it is passed to the method, in which case it is an object called xml, as it is in the code. To set a value for a property has to pass an argument, and it is the repositorio.xmlRetorno it must be in the code somewhere (it would be better if it had all the code). If it were a method it could have other arguments so it accepts a array.

using static System.Console;
using System.Reflection;

public class Program {
    public static void Main() {
        var xml = new Servico();
        var tipoServico = xml.GetType();
        tipoServico.InvokeMember("SalvarXmlRetornoEm", BindingFlags.SetProperty, null, xml, new object[] { "local" });
        WriteLine(xml.SalvarXmlRetornoEm);
    }
}

//pra simplificar vou fazer um tipo em código mesmo

public class Servico {
    public string SalvarXmlRetornoEm { get; set; }
}

Behold working in the ideone. And in the .NET Fiddle. Also put on the Github for future reference.

If you know the type and you know the property at compile time, why do this? Maybe the code was written by someone who doesn’t know what he’s doing.

#Simplifying the code

The mechanism of reflection is not necessary in this case. It is rare that it is necessary, except in frameworks that need to automate internal tasks that could be done with normal code, but with much more work, or if you need to accomplish something only known at runtime. This is not the case, reflection only worsens this code.

Reinforce what I started writing in the reply: if you know the name of the members you want to access has no reason to use reflection. I quote in particular pegar todos os métodos ou propriedades. If you will catch a specific already know his name and need no reflection.

I will not criticize its use there because few people understand the use of reflection and that genericity is usually a much better mechanism. To tell you the truth I think it doesn’t even need to be generic, it can be the traditional polymorphic. I don’t know if I need to change anywhere else, maybe I need to virtualize the properties of TaskAbst (default name). No virtualizing, only works with generics.

It would be a lot of work for me to rewrite the whole code here in response to be generic or polymorphic instead of reflective, which is safer and performative, but you could do something like this:

private void EnviarArquivo(Empresa empresa, string arquivoXmlEnvio, string localSalvarXmlRetorno, TaskAbst nfe) {
    nfe.NomeArquivoXML = arquivoXmlEnvio;
    nfe.SalvarXmlRetornoEm =  localSalvarXmlRetorno;
    nfe.Execute();
}

You have how to do the parameter metodo but it would take a little more work and add a complicator. Even a way would be to pass the variable itself servico of switch to define what to call, if you really need to. I couldn’t even adapt because there is no documentation or example of use how to use this parameter. I don’t think he’s even necessary.

Obviously everything that the flame will have to be changed to call the right way, I’ll take an example from switch in the same class just to illustrate:

CertVencido(empresa);
IsConnectedToInternet();
switch (servico) {
    case Servicos.ConsultarLoteRps:
        EnviarArquivo(empresa, arquivoXmlEnvio, localSalvarXmlRetorno, new TaskConsultarLoteRps());
        break;
    ...

Note that I already gave a simplified code. I saw a huge amount of problems in this and other classes, that is, the code is very poorly written. To be perfectly honest, no bullshit, it’s tragic. I recognize the effort of those who did, but he is not good, although it should help a lot of people and this has merit.

Nor would that be necessary. Nor the switch would need to be used. Polymorphism could be adopted to achieve the goal, which would be a beneficial object-oriented use, unlike most of the OOP code that people do that serves no useful purpose.

  • I added a more complete part of the code, it is because I am developing an application for emission of Nfse and I am using the lib NFSE.NET that is in github as an example, and I came across this method rs... in the last snippet of code that I put in the question ha in the last line one (System.Reflection.Bindingflags.Invokemethod), would this be to invoke an already created method? if you can help me understand this part also I thank you rsrs...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.