IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Remoting and Reflection : comment faire?


Sujet :

C#

  1. #1
    Membre régulier Avatar de Piet
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    111
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 111
    Points : 108
    Points
    108
    Par défaut Remoting and Reflection : comment faire?
    Bonjour,

    Par la "reflection", il est possible d'envoyer le nom de la méthode et ses paramètres pour l'exécution au travers de InvokeMember(...)

    Dans une exécution sur le poste local, pas de problème, ceci fonctionne bien, mais par contre lorsque je travaille avec du remoting, je ne sais pas comment passer les arguments à InvokeMember. Soit le type est vu comme un proxy et je ne sais pas faire grand chose, soit le type est forcément mauvais (puisque l'interface n'implémente rien)

    Après avoir cherché, je suis tombé sur http://blogs.msdn.com/manishg/archiv...09/227400.aspx, mais ceci ne m'aide pas...

    Quelqu'un peut-il m'aider?

    Voici de plus amples informations sur le contexte (si ça peut aider à la compréhension) :

    IRemoteOperation.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    namespace RemotingInterfaces
    {
        public interface IRemoteOperation
        {
            bool Action(type1 param1, type2 param2, ...);
        }
    }
    RemoteOperations.cs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    namespace RemotingInterfaces
    {
        public class RemoteOperation : MarshalByRefObject, RemotingInterfaces.IRemoteOperation
        {
            bool Action(type1 param1, type2 param2, ...)
            {
                // Action is executed here
            }
        }
    }
    Ceci fonctionne très bien et m'exécute bien l'action sur le pc souhaité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    RemotingInterfaces.IRemoteOperation op;
    string pcName = "PC-DE-TEST";
    int port = 12345;
    op = (RemotingInterfaces.IRemoteOperation)Activator.GetObject(
        typeof(RemotingInterfaces.IRemoteOperation),
        "tcp://" + pcName + ":"+port.ToString()+"/RemoteOperation");
     
    bool b = op.Action(Param1, Param2, ...)
    Pour une économie et une réutilisation du code, je souhaite envoyer toutes les actions vers une fonction plus générale :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bool GeneralAction( string action, object [] params)
    Ceci pourra me permettre de faire les mêmes opérations de vérification pour toutes les actions.

    Pour une exécution locale, je n'ai pas de problème :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    private bool LocalExecute(string action, object[] myParams)
    {
        Type type1 = typeof(RemoteOperation);
        object obj = Activator.CreateInstance(type1);
        bool res = (bool)type1.InvokeMember(action, System.Reflection.BindingFlags.InvokeMethod, null, obj, myParams);
    }

    Par contre, pour exécuter sur le client, je n'arrive pas à prendre le type de op et donc de pouvoir passer par l'interface :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    private bool RemoteExecute(string action, object[] myParams, string pcName, DateTime expirationDate)
    {
        Type myType = typeof(IRemoteOperation);
        string url = "tcp://" + pcName + ":"+port.ToString()+"/RemoteOperation";
        op = (IRemoteOperation)Activator.GetObject(myType,url);
        //Ce qui suit est faux!
        Type type2 = typeof(IRemoteOperation);
     
        bool res2 = (bool)type2.InvokeMember(action, System.Reflection.BindingFlags.InvokeMethod,null, op, myParams);
     
    }
    Comment faire?

    Toute solution est la bienvenue.

    Merci d'avance.
    Piet

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    et en invokant un membre de l'interface avec de la reflection sur l'interface ?
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre régulier Avatar de Piet
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    111
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 111
    Points : 108
    Points
    108
    Par défaut
    C'est bien ce que j'essaie de faire, mais je ne vois pas trop comment... C'est ce que la dernière frame de code montre.

    En gros, de quoi dois-je faire un "CreateInstance()" ?
    Piet

  4. #4
    Membre régulier Avatar de Piet
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    111
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 111
    Points : 108
    Points
    108
    Par défaut
    On peut faire un invokemember sur un membre d'interface?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    Type myType = typeof(IRemoteOperation);//type1.GetInterface("RemotingInterfaces.IRemoteOperation");
     
    string url = "tcp://" + pcName + ":"+port.ToString()+"/RemoteOperation";
    IRemoteOperation theRemoteOperation = null;
    theRemoteOperation = (IRemoteOperation)Activator.GetObject(myType,url);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    object objro01 = Activator.CreateInstance(myType);
    Crée une exception :
    "impossible de créer une interface"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    object objro02 = Activator.CreateInstance(theRemoteOperation.GetType());
    crée une exception :
    "impossible de créer une méthode abstraite"

    Une idée?

    Je ne vois plus clair...
    Piet

  5. #5
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    si c'est pour instancier des objets, on ne peut pas avec juste une interface (trouver une méthode encore ca devrait etre faisable)

    donc si tu veux créer une instance dont le type est sur le serveur, je pense qu'il faut que tu demandes l'instance au serveur qui lui aura accès aux classes
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre régulier Avatar de Piet
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    111
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 111
    Points : 108
    Points
    108
    Par défaut
    ok... Et comment puis-je faire ça?
    Piet

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    et bien le remoting sert à exposer des membres du serveur au client
    du fait une fonction qui instancie un machin et le retourne
    et le client l'appelle
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Membre régulier Avatar de Piet
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    111
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 111
    Points : 108
    Points
    108
    Par défaut
    Mais j'ai normalement accès aux membres du serveur

    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    RemotingInterfaces.IRemoteOperation op;
    string pcName = "PC-DE-TEST"; 
    int port = 12345;
    op = (RemotingInterfaces.IRemoteOperation)Activator.GetObject(
        typeof(RemotingInterfaces.IRemoteOperation),
        "tcp://" + pcName + ":"+port.ToString()+"/RemoteOperation");
     
    bool b = op.Action(Param1, Param2, ...)
    je souhaiterais juste pouvoir faire un

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool b = (bool)TypeX.InvokeMember("op."+action, myParams);
    à la place de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool b = op.Action(Param1, Param2, ...)
    Ai-je vraiment besoin de demander une instance au serveur pour ça?

    Le problème, c'est que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bool b = (bool)theRemoteOperation.GetType().InvokeMember(action, System.Reflection.BindingFlags.InvokeMethod, null, theRemoteOperation, myParams);
    donne :
    Méthode 'System.MarshalByRefObject.PopUp' introuvable.
    où action= "PopUp", existe dans la classe et dans l'interface.

    De toute façon, le serveur ne peut me répondre que les types suivants :
    - IRemoteOperation
    - RemoteOperation
    et le client ajoutera :
    - System.MarshalByRefObject

    A la limite, je veux même bien le fixer en dur, mais ça ne changera rien que ce soit le serveur qui me réponde "IRemoteOperation" ou que je le fixe...
    Piet

  9. #9
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    je suis pas vraiment expert en remoting, mais vu que t'avais pas spécialement de réponse j'ai tenté ma chance
    de plus je comprends pas trop ton code et ce que tu veux faire

    mais le principe du remoting c'est une interface commune de chaque coté
    cette interface est implémentée de chaque coté par des classes qui peuvent etre différentes
    le serveur se met en écoute et expose une classe implémentant l'interface
    quand un client se connecte il instancie un élement de la classe coté serveur
    et le client voit cette instance
    ensuite il peut appeler des membres de l'interface et c'est le serveur qui répond
    et pour avoir accès aux membres coté client on cast l'instance retournée par le serveur sur l'interface, il n'y a donc rien à instancier ..
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  10. #10
    Membre régulier Avatar de Piet
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    111
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 111
    Points : 108
    Points
    108
    Par défaut
    Sorry, je m'en veux énormément...

    En fait, ça fonctionne très bien et sans doute depuis le début... Le seul problème était dû au comportement de la machine car le même exe était toujours dans la liste des processus... :-s et donc, certaines info ne revenaient pas... Le pire, c'est que ça m'était déjà arrivé il y a quelques années et que j'avais pesté de la même façon...

    Vraiment désolé pour le dérangement Pol63... et merci pour tes tentatives de résolution.
    Piet

  11. #11
    Membre régulier Avatar de Piet
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    111
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2004
    Messages : 111
    Points : 108
    Points
    108
    Par défaut
    Oui, c'est bien ça le remoting...

    C'est surtout pour avoir une définition commune au client et au serveur et avoir une communication bidirectionnelle que je l'utilise en fait.

    Merci pour ton aide en tout cas.
    Piet

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment faire du drag and drop dans un Listbox
    Par jca dans le forum Codes sources à télécharger
    Réponses: 0
    Dernier message: 08/02/2013, 20h54
  2. Comment faire fonctionner Remote System Explorer ?
    Par coolben dans le forum Eclipse PHP
    Réponses: 0
    Dernier message: 12/03/2010, 13h50
  3. GCC AND XLC comment faire
    Par eljuventino dans le forum Linux
    Réponses: 11
    Dernier message: 01/07/2009, 12h33
  4. Réponses: 2
    Dernier message: 28/05/2008, 11h15
  5. Comment faire pour créer un bitmap
    Par GliGli dans le forum C++Builder
    Réponses: 2
    Dernier message: 24/04/2002, 15h41

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo