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 :

Reflection et classe héritant de ConfigurationSection


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 4
    Par défaut Reflection et classe héritant de ConfigurationSection
    J'ai besoin de faire une application modulaire dont un des module stocke ses propriétés dans le app.config. J'ai créé une dll contenant ce fameux module. Il contient uniquement une classe héritant de ConfigurationSection et implémentant une interface générique de mon cru (ICanalGenerique).

    Le noyau implémentant les modules n'a connaissance que de mon interface générique, les dll étant gérées par pluggin. J'utilise donc la reflection pour instancier ma classe contenue dans la dll.

    J'ai fait un test direct de ma dll sans passer par la reflection et mon objet charge bien ses propriétés depuis le app.config, en utilisant ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    using System;
    using System.Linq;
    using System.Configuration;
    using System.IO;
    using Copilote.CanalUNC;
    using Copilote.CanalGenerique;
     
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main()
        {
          CanalUNC section = (CanalUNC)ConfigurationManager.GetSection("CanalUNC");
          Console.WriteLine("{0} ; {1}", section.DirectoryAsc, section.DirectoryAscSave);
          Console.ReadLine();
        }
      }
    }
    Par contre, je ne trouve pas de moyen pour le faire via la reflection ; mon code dans ce cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    using System;
    using System.Collections.Specialized;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Copilote.GestionLog;
    using Copilote.CanalGenerique;
    using System.IO;
    using System.Reflection;
    using System.Configuration;
     
    namespace TestEchanges
    {
     class Program
     {
      static void Main(string[] args)
      {
       LogSingleton.Instance.IsChronodate = true;
       LogSingleton.Instance.AddEntry(null, new LogEventArgs(TypeLog.Noyau, TypeErreur.Information, "Démarrage de l'application."));
       NameValueCollection appSettings = ConfigurationManager.AppSettings;
       NameValueCollection configSettings = null;
       for (int i = 0; i < appSettings.Count; i++)
       {
        if (appSettings.GetKey(i) == "Config")
         configSettings = (NameValueCollection)ConfigurationManager.GetSection(appSettings[appSettings.GetKey(i)]);
       }
       Assembly monAssembly = Assembly.LoadFrom(Path.Combine(Environment.CurrentDirectory, configSettings["Canal"]));
       // Introspection des types
       ICanalGenerique monCanal;
       foreach (Type type in monAssembly.GetTypes())
       {
        if (type.GetInterface(typeof(ICanalGenerique).FullName) != null)
        {
         // Un type correspond, création d'un objet
         monCanal = (ICanalGenerique)Activator.CreateInstance(type, ConfigurationManager.GetSection("CanalUNC"));
         // Liaison de l'événement à la fonction de traçage
         monCanal.RaiseLogEvent += LogSingleton.Instance.AddEntry;
     
         // Tentative de lecture
         MemoryStream monStream = new MemoryStream();
         monCanal.GetData(ref monStream);
     
         byte[] byteArray = new byte[monStream.Length];
         var count = monStream.Read(byteArray, 0, (int)monStream.Length);
     
         Console.WriteLine(Encoding.Default.GetString(byteArray));
        }
       }
     
       // On attend...
       Console.ReadLine();
      }
     }
    }
    Qu'est ce que je fait de travers ?

    Merci d'avance !

  2. #2
    Membre à l'essai
    Homme Profil pro
    Inscrit en
    Avril 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2011
    Messages : 4
    Par défaut
    J'ai contourné mon problème en partant d'un objet déclaré en ConfigurationSection et en appelant mes méthodes interfacées via le InvokeMember...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    // Introspection des types
          foreach (Type monType in canalAssembly.GetTypes())
          {
            // Si la classe présente dans l'assembly implémente une ICanalGenerique, il s'agit d'un canal
            if (monType.GetInterface(typeof(ICanalGenerique).FullName) != null)
            {
              // On part du principe que tout objet géré par le noyau hérite de ConfigurationSection, ce qui permet de sauvegarder les propriétés dans le app.config
              ConfigurationSection monCanal = null;
              // Un type correspond, création d'un objet
              monCanal = (ConfigurationSection)Activator.CreateInstance(monType);
              // On lui colle la section du app.config correspondante
              monCanal = (ConfigurationSection)ConfigurationManager.GetSection(monType.Name);
     
              try
              {
                // Liaison de l'événement à la fonction de traçage
                // On fait un appel du style monCanal.RaiseLogEvent += LogSingleton.Instance.AddEntry; mais en utilisant la reflection
                // On récupère un pointeur sur l'événement
                EventInfo evClick = monType.GetEvent("RaiseLogEvent");
                // Puis son type
                Type tDelegate = evClick.EventHandlerType;
                // On fabrique un handler sur la fonction à lier
                MethodInfo myHandler = typeof(GestionLog).GetMethod("AddEntry", BindingFlags.Public | BindingFlags.Instance);
                // On crée le délégué sur la fonction à lier
                Delegate d = Delegate.CreateDelegate(tDelegate, GestionLog.Instance, myHandler);
                // On récupère le pointeur sur la fonction
                MethodInfo addHandler = evClick.GetAddMethod();
                // Par reflection, on lie le bazard
                addHandler.Invoke(monCanal, new Object[] { d });
              }
              catch
              {
                GestionLog.Instance.AddEntry(null, new LogEventArgs(TypeLog.Noyau, TypeErreur.Information, "Erreur de liaison du Log au Canal."));
              }
     
              // Tentative de lecture
              monStream = new MemoryStream();
              // Puisqu'on sait qu'il s'agit d'un canal, l'objet doit avoir la methode 'GetData'
              // On fait un appel du style monCanal.GetData(ref monStream); mais en utilisant la reflection
              bool Result = false;
              try
              {
                Result = (bool)monCanal.GetType().InvokeMember("GetData", BindingFlags.Default | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, monCanal, new object[] { monStream });
              }
              catch (MissingMethodException mme)
              {
                // Dans le cas ou la méthode n'est pas un membre de ce type ...
                Console.WriteLine("Méthode 'GetData' introuvable : " + mme.Message);
              }

    Et c'est opérationnel...

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

Discussions similaires

  1. class héritant de Form, impossible à utiliser ?
    Par Pol63 dans le forum VB.NET
    Réponses: 9
    Dernier message: 01/06/2007, 09h25
  2. Réponses: 5
    Dernier message: 03/12/2006, 15h55
  3. Afficher une image dans une classe héritant de Jframe
    Par condor_01 dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 27/04/2006, 22h11
  4. Pb: Classe héritant de TForm
    Par XeN-Lo dans le forum C++Builder
    Réponses: 4
    Dernier message: 15/04/2006, 15h30
  5. [CSS] Classe héritant déf d une autre classe?!
    Par Trunks dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 08/01/2006, 23h43

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