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++/CLI Discussion :

Externaliser les donn�es d'un Dictionary


Sujet :

C++/CLI

  1. #1
    Membre tr�s actif
    Profil pro
    Inscrit en
    D�cembre 2007
    Messages
    254
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2007
    Messages : 254
    Par d�faut Externaliser les donn�es d'un Dictionary
    Bonjour,
    a fin d'�viter que le dictionnaire ne se charge au d�marrage je souhaite le cr�er dans un data.h ou un fichier externe a l'application ex data.** ce qui faciliterai les ajout futur mais je n'y arrive pas.
    Actuellement mon dictionnaire est int�gr� � l'appli comme si dessous.
    Merci d'avance pour votre aide.

    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
     
    	public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    		Form1(void)
    		{
    			InitializeComponent();
     
    			dict = gcnew Dictionary< String^, TwoStrings^ >;
    			TwoStrings ^TwoStrs = gcnew TwoStrings;
    			TwoStrs = gcnew TwoStrings;
    			TwoStrs->first = L"arbre";
    			TwoStrs->second = L"ete";
    			dict->Add(L"3452", TwoStrs);TwoStrs = gcnew TwoStrings;
     
            }
            private 
     
    		Dictionary<String, FourStrings> dict;
    Et dans un autre fichier d'en-t�te.h la classe FourStrings
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    namespace dico {
    	using namespace System;
     
    	public ref class FourStrings {
    	public:
    		String^ first;
    		String^ second;
    		String^ three;
     	        String^ four;
    	};
    }

  2. #2
    Membre tr�s actif
    Profil pro
    Inscrit en
    D�cembre 2007
    Messages
    254
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2007
    Messages : 254
    Par d�faut
    Es ce possible de mettre mon dico dans un dataTable? ou autre base?
    Un exemple serait le bien venu,merci.

  3. #3
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 504
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 504
    Par d�faut
    La m�thode de feignant : Google :

    http://weblogs.asp.net/pwelter34/arc...03/444961.aspx

    Il y a peut-�tre plus �l�gant en .NET4.

    Avec ce dictionnaire serialisable, vous mettez vos donn�es dans le fichier de configuration au format attendu par cette classe et vous chargez ce dictionnaire comme une ressource standard.
    What else.

  4. #4
    Membre tr�s actif
    Profil pro
    Inscrit en
    D�cembre 2007
    Messages
    254
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2007
    Messages : 254
    Par d�faut

    Bonsoir,

    Je cherche depuis un bon moment sur Google mais le xml j'ai pr�f�r� laisser e cot� car je n'y connais rien.

    Dans la classe si j'ai bien compris il me faut dans :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    public System.Xml.Schema.XmlSchema GetSchema() 
    //créer un schéma pour la Tkey et la Tvalue 
    //Dans un fichier xml écrire mes  TKey,TValue. 
    while (reader.NodeType != System.Xml.XmlNodeType.EndElement){...}
    //Je comprend pas la démarche pour lire, chercher et afficher.
    Le fichier XML peut il �tre externe � l'application ou forc�ment inclus?
    D�sol� si mes questions peuvent para�tre stupides mais sans r�ponses il m'est difficile d'avancer.

  5. #5
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 504
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 504
    Par d�faut
    mais le xml j'ai pr�f�r� laisser e cot� car je n'y connais rien.
    Vous allez voir, ce n�est pas trop compliqu� et c'est super pratique.

    Le principe de la solution que je vous montre est simple.
    On utilise le principe de la s�rialisation et d�s�rialisation.
    La s�rialisation, c'est transformer un objet en chaine de caract�re.
    Et la d�s�rialisation, c'est transformer une cha�ne de caract�re en objet.

    On va donc prendre le contenu d'un fichier comme chaine en entr� du m�canisme de d�s�rialisation et obtenir votre cher dictionnaire.

    Une m�thode de s�rialisation/d�s�rialisation est d'utiliser le XML comme format de chaine de caract�re.

    Le seul truc un peu compliqu�, c'est que .NET (m�me la version 4, apr�s un petit teste) interdit la s�rialisation des IDictionary donc des objets de la classe Dictionary<T,U>.

    On va donc cr�er une classe d�rivant de Dictionary<T,U> et qui sera s�rialisable.

    En convertissant, � l'arrache, le code C# trouv� � cette URL :
    http://www.dacris.com/blog/2010/07/3...ngExample.aspx
    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
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    using namespace System;
    using namespace System::Collections::Generic;
    using namespace System::IO;
    using namespace System::Runtime::Serialization;
    using namespace System::Xml;
    using namespace System::Xml::Serialization;
    using namespace System::Xml::Schema;
     
    generic <typename TKey, typename TVal>
    [Serializable()]
    public ref class SerializableDictionary : Dictionary<TKey,TVal>, IXmlSerializable, ISerializable
    {
    private :
    	static String^ DictionaryNodeName = "Dictionary";
    	static String^ ItemNodeName = "Item";
    	static String^ KeyNodeName = "Key";
    	static String^ ValueNodeName = "Value";
     
    public:
    	SerializableDictionary(){}
     
    	SerializableDictionary(IDictionary<TKey, TVal>^ dictionary)
    		: Dictionary<TKey,TVal>(dictionary)
    	{}
     
    	SerializableDictionary(IEqualityComparer<TKey>^ comparer)
    		: Dictionary<TKey,TVal>(comparer)
    	{}
     
    	SerializableDictionary(int capacity)
    		: Dictionary<TKey,TVal>(capacity)
    	{}
     
    	SerializableDictionary(IDictionary<TKey, TVal>^ dictionary, IEqualityComparer<TKey>^ comparer)
    		: Dictionary<TKey,TVal>(dictionary, comparer)
    	{}
     
    	SerializableDictionary(int capacity, IEqualityComparer<TKey>^ comparer)
    		: Dictionary<TKey,TVal>(capacity, comparer)
    	{}
     
    protected :
     
    	SerializableDictionary(SerializationInfo^ info, StreamingContext* context)
    	{
    		int itemCount = info->GetInt32("ItemCount");
     
    		for (int i = 0; i < itemCount; i++)
    		{
    			KeyValuePair<TKey, TVal>^ kvp = (KeyValuePair<TKey, TVal>^)info->GetValue(String::Format("Item{0}", i), KeyValuePair<TKey, TVal>::typeid );
    			this->Add(kvp->Key, kvp->Value);
    		}
    	}
     
    public :
     
    	virtual void GetObjectData(SerializationInfo^ info, StreamingContext context) override = ISerializable::GetObjectData
    	{
    		info->AddValue("ItemCount", this->Count);
     
    		int itemIdx = 0;
    		for each (KeyValuePair<TKey, TVal>^ kvp in this)
    		{
    			info->AddValue(String::Format("Item{0}", itemIdx), kvp, KeyValuePair<TKey, TVal>::typeid);
    			itemIdx++;
    		}
     
    	}
     
    	virtual void WriteXml(XmlWriter^ writer) = IXmlSerializable::WriteXml
    	{
    		//writer.WriteStartElement(DictionaryNodeName);
     
    		for each (KeyValuePair<TKey, TVal>^ kvp in this)
    		{
    			writer->WriteStartElement(ItemNodeName);
    			writer->WriteStartElement(KeyNodeName);
    			KeySerializer->Serialize(writer, kvp->Key);
    			writer->WriteEndElement();
    			writer->WriteStartElement(ValueNodeName);
    			ValueSerializer->Serialize(writer, kvp->Value);
    			writer->WriteEndElement();
    			writer->WriteEndElement();
    		}
     
    		//writer.WriteEndElement();
    	}
     
    	virtual void ReadXml(XmlReader^ reader) = IXmlSerializable::ReadXml
    	{
    		if (reader->IsEmptyElement)
    		{
    			return;
    		}
     
    		// Move past container
     
    		if (!reader->Read())
    		{
    			throw gcnew XmlException("Error in Deserialization of Dictionary");
    		}
     
    		//reader.ReadStartElement(DictionaryNodeName);
     
    		while (reader->NodeType != XmlNodeType::EndElement)
    		{
    			reader->ReadStartElement(ItemNodeName);
    			reader->ReadStartElement(KeyNodeName);
    			TKey key = (TKey)KeySerializer->Deserialize(reader);
    			reader->ReadEndElement();
    			reader->ReadStartElement(ValueNodeName);
    			TVal value = (TVal)ValueSerializer->Deserialize(reader);
    			reader->ReadEndElement();
    			reader->ReadEndElement();
    			this->Add(key, value);
    			reader->MoveToContent();
    		}
     
    		//reader.ReadEndElement();
     
    		reader->ReadEndElement(); // Read End Element to close Read of containing node
    	}
     
    	virtual XmlSchema^ GetSchema() = IXmlSerializable::GetSchema
    	{
    		return nullptr;
    	}
     
    protected :
    	property XmlSerializer^ ValueSerializer
    	{
    		XmlSerializer^ get()
    		{
    			if (valueSerializer == nullptr)
    			{
    				valueSerializer = gcnew XmlSerializer(TVal::typeid);
    			}
    			return valueSerializer;
    		}
    	}
     
    private :
    	property XmlSerializer^ KeySerializer
    	{
    		XmlSerializer^ get()
    		{
    			if (keySerializer == nullptr)
    			{
    				keySerializer = gcnew XmlSerializer(TKey::typeid);
    			}
    			return keySerializer;
    		}
    	}
     
    	XmlSerializer^ keySerializer;
    	XmlSerializer^ valueSerializer;
    };
    En utilisant un SerializableDictionary en lieu et place d'un Dictionary, vous pourrez le s�rialiser et le d�s�rialiser.

    Pour que la classe issue de l'expansion de la classe g�n�rique SerializableDictionary reste s�rialisable et d�s�rialisable, il faut que le type du param�tre g�n�rique soit aussi un type s�rialisable.

    Voici en exemple de classe s�rialisable.
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Serializable()]
    public ref class Values
    {
    public :
    	Values(){};
    	Values(String ^ s1, String ^ s2){Value1 = s1; Value2 = s2;};
     
    	String^ Value1;
    	String^ Value2;
    };
    Remarquez l'attribut [Serializable()], le constructeur public sans param�tre et les champs avec une visibilit� "public". C'est un moyen simple de rendre la classe s�rialisable et d�s�rialisable.

    Il ne reste plus qu'� avoir un simple fichier texte correctement format�, comme celui-ci:
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?xml version="1.0" encoding="utf-8"?>
    <SerializableDictionaryOfStringValues>
      <Item>
        <Key>
          <string>cle1</string>
        </Key>
        <Value>
          <Values>
            <Value1>text1</Value1>
            <Value2>text2</Value2>
          </Values>
        </Value>
      </Item>
    </SerializableDictionaryOfStringValues>
    Le format du fichier est fonction de la classe de la cl� et de la classe des entr�es dans le dictionnaire. Dans notre exemple c'est "String ^" et "Values ^".
    Si vous utilisez d�autres types comme param�tres g�n�rique, il faudra modifier le format du fichier. Dans le code ci-apr�s, la m�thode "create", mise en commentaire, permettra de g�n�rer un fichier contenant un objet s�rialis� correctement format� qui vous servira d'exemple en cas de besoin. Cette m�thode utilise la s�rialisation d'un objet SerializableDictionary<T,U>.

    Pour pouvoir cr�er le dictionnaire, rien de plus simple, il suffit d'utiliser la classe XmlSerializer^ pour le r�cup�rer depuis le contenu du fichier, comme le montre le code la m�thode "read" ci-apr�s.

    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
    void create(XmlSerializer^ serializer)
    {
    	SerializableDictionary<String ^, Values ^>^ dico = gcnew SerializableDictionary<String ^, Values ^>;
    	Values ^ element = gcnew Values("text1","text2");
    	dico->Add("cle1", element);
     
    	TextWriter^ writer = gcnew StreamWriter( "test.xml" );
    	serializer->Serialize( writer, dico );
    	writer->Close();
    }
     
    SerializableDictionary<String ^, Values ^>^ read(XmlSerializer^ serializer)
    {
    	TextReader^ reader = gcnew StreamReader( "test.xml" );
    	SerializableDictionary<String ^, Values ^>^ ret = (SerializableDictionary<String ^, Values ^>^) serializer->Deserialize( reader);
    	reader->Close();
    	return ret;
    }
     
    int main(array<System::String ^> ^args)
    {
    	XmlSerializer^ serializer = gcnew XmlSerializer( SerializableDictionary<String ^, Values ^>::typeid );
    	//create(serializer);
     
    	SerializableDictionary<String ^, Values ^>^ dico = read(serializer);
     
    	Values^ Values = dico["cle1"];
    	return 0;
    }
    L'utilisation du XML permet d'avoir un fichier texte extr�mement facile � modifier et simple avec un minimum de connaissance en XML.

  6. #6
    Membre tr�s actif
    Profil pro
    Inscrit en
    D�cembre 2007
    Messages
    254
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2007
    Messages : 254
    Par d�faut

    Ok j'ai compris dans les grandes lignes, mais �a commence mal, je n'arrive pas a declarer la classe XmlSerializer^ ,j'ai juste fait un copier coller du code de la classe dans un projet vide et �a refuse de compiler avec l'erreur:
    error C2065: 'SerializableDictionary'*: identificateur non d�clar�

    J'ai bien entendu mis les namespaces comme vous les avez d�crit.
    Dois-je d�clarer cette classe dans un autre fichier .h ?

  7. #7
    Expert confirm�
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    F�vrier 2005
    Messages
    5 504
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : France, Val de Marne (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : F�vrier 2005
    Messages : 5 504
    Par d�faut
    D�sol� pour le retard.

    'SerializableDictionary' est une classe d�finie dans le premier bloc "Code" de mon dernier post.

    Normalement, en mettant le premier bloc "Code", le premier bloc "Quote" (une erreur, vue que c'est du code) et le deuxi�me et dernier bloc "Code" dans un seul fichier cpp, cela compilera.

    A vous d'organiser votre code en fichier selon vos habitudes.

Discussions similaires

  1. R�ponses: 3
    Dernier message: 20/01/2011, 02h00
  2. R�ponses: 4
    Dernier message: 04/12/2003, 08h12
  3. R�ponses: 13
    Dernier message: 14/10/2003, 14h31
  4. R�ponses: 4
    Dernier message: 18/08/2003, 09h53
  5. trier les donn�es dans le cache ??
    Par psyco2604 dans le forum XSL/XSLT/XPATH
    R�ponses: 31
    Dernier message: 10/06/2003, 10h03

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