Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

.NET 2.0 Configuration Classes

Îåêßíçóå áðü ôï ìÝëïò BruteForce. Τελευταία δημοσίευση από το μέλος BruteForce στις 02-12-2005, 14:33. Υπάρχουν 7 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  01-12-2005, 22:07 7484

    .NET 2.0 Configuration Classes

    Συνημμένα: Configuration.zip

    Σήμερα έφαγα λίγο χρόνο με τις νέες κλάσεις που έχει το .ΝΕΤ 2.0 για τη διαχείριση των configuration files. To μεγάλο νέο είναι ότι πλέον μπορείς να γράψεις σε ένα configuration αρχείο. Το documentation είναι imho κάκιστο, αλλά τελικά έβγαλα άκρη στο τι ήθελα να κάνω και μετά καθάρισε ο reflector Smile [:)]. Επειδή το αποτέλεσμα μπορεί να φανεί χρήσιμο και σ'άλλους είπα να το βάλω στο dotNetZone.

    Το πρόγραμμα που φτιάχνω ξεκινάει διαβάζοντας μια σειρά από αρχεία mdb από τα οποία αντλεί δεδομένα. ¨Ηθελα λοιπόν να έχω το ποια είναι αυτά τα αρχεία μέσα στο .config της εφαρμογής σε μια μορφή όπως η εξής:

    <configuration>
      ...
      <metadataFilesInfo>
       
    <
    metadataFiles
    >
          <
    add filename="NUNIT1.MDB" description="NUnint Test MDB 1" options="Normal"
    />
          <
    add filename="NUNIT2.MDB" description="NUnint Test MDB 2" options="Normal"
    />
          <
    add filename="NUNIT3.MDB" description="NUnint Test MDB 3" options="IgnoreErrors"
    />
          <
    add filename="NUNIT4.MDB" description="NUnint Test MDB 4"
    />
        </
    metadataFiles>
        ...

      </metadataFilesInfo>
    <configuration>

    To metadataFilesInfo είναι αυτό που ονομάζεται Section Group, ενώ το metadataFiles είναι ένα section. Ένα section επιτρέπεται να εμφανίζεται μόνο μία φορά μέσα στο αρχείο. Μπορεί να προσδιορίζει settings σαν attributes του xml element. Όταν όμως χρειάζεται μια λίστα από εγγραφές όμοιες μεταξύ τους εκεί πρέπει να παίξουμε ένα επίπεδο πιο μέσα με το add ενώ για να διαβάσουμε τις εγγραφές μέσω μιας κλάσης πρέπει να ακολουθήσουμε την τεχνική που περιγράφω παρακάτω.

    Αυτό που χρειάζεται είναι να φτιαχτεί (με τον .ΝΕΤ 2.0 τρόπο) μια κλάση για το custom section metadataFiles. Αυτή η κλάση θα έχει για member της ένα collection κάποιου τύπου μέσω του οποίου γίνονται προσπελάσιμες οι εγγραφές. In principle ακούγεται απλό. Ένας κώδικας που διαβάζει αλλά και γράφει το configuration file είναι ο εξής:

    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    ConfigurationSectionGroup csg = config.SectionGroups["metadataFilesInfo"
    ];
    MetadataFilesSection mfs = csg.Sections["metadataFiles"] as MetadataFilesSection
    ;
    System.Collections.
    IEnumerator
    enumerator = mfs.MetadataFiles.GetEnumerator();
    while
    (enumerator.MoveNext())
    {
       
    MetadataFileInfo info = (MetadataFileInfo
    )enumerator.Current;
       
    Console.WriteLine(info.FileName + " Description: " + info.Description + " Options: "
    + info.Options);
    }

    // Make some change
    enumerator.Reset();
    enumerator.MoveNext();
    MetadataFileInfo mfi = (MetadataFileInfo
    )enumerator.Current;
    mfi.Options =
    "Optional"
    ;
    config.Save();

    Ο κώδικας νομίζω είναι σχετικά απλός. MetadataFileInfo είναι η κλάση που αντιστοιχεί σε κάθε γραμμή του configuration file, ενώ MetadataFilesSection η κλάση που αντιστοιχεί στο section.

    Ο κώδικας για το πώς πρέπει να φτιαχτούν αυτές οι κλάσεις είναι attached στο post, καθώς και το app.config με τις δηλώσεις του section group και του section.

    Ελπίζω να φανεί χρήσιμο Smile [:)]

    Brute Force


    The fact that the program works is irrelevant.
  •  02-12-2005, 08:10 7487 σε απάντηση της 7484

    Απ: .NET 2.0 Configuration Classes

    Στο .NET Framework 1.1 πέρα από το ότι δεν μπορούσες να γράψεις στο config file, υπάρχει και ένας άλλος περιορισμός κατά τον οποίο ό,τι διαβάζεις από το configuration file είναι ό,τι περιέχεται την στιγμή που ξεκινάει η εφαρμογή σου. Δηλαδή, αν όσο τρέχει η εφαρμογή, αλλάξεις τιμή σε κάποια παράμετρο του configuration file, αυτή τη αλλαγή θα την "αντιληφθεί" ο config reader στην επόμενη εκκίνηση του προγράμματος. Κάτι τέτοιο οδηγεί πολλές φορές στο αναπόφευκτο "οι αλλαγές σας θα ισχύσουν την επόμενη φορά που θα εκκινήσετε την εφαρμογή" dialog box και άλλοτε περιπλέκει τον κώδικα αφού έχεις δύο σενάρια για configuration change, το πρώτο να διαβάζει το config και το δεύτερο να κάνει assign τις αλλαγές πάνω στα objects, κλπ. Γι αυτόν το λόγο, συνήθως κάνω access τα config settings απευθείας μέσω δικής μου κλάσης. Μιας και το ψάχνεις το θέμα, έχει αλλάξει τίποτα σε αυτό; Θα ήταν καλό να ξεφορτωθώ αυτό το wrapper...


    Vir prudens non contra ventum mingit
  •  02-12-2005, 10:28 7493 σε απάντηση της 7487

    Απ: .NET 2.0 Configuration Classes

    Οι δοκιμές που έκανα δείχνουν ότι αν το αρχείο .config τροποποιηθεί εξωτερικά οι νέες κλάσεις ΔΕΝ βλέπουν τις αλλαγές, ακόμα και αν καλέσεις ξανά την ConfigurationManager.OpenExeConfiguration(). Αν οι αλλαγές γίνουν μέσω των configuration κλάσεων τότε αυτές είναι αμέσως visible όταν ξαναδιαβαστεί το setting, είτε μέσω ενός ήδη ανοικτού Configuration object ή μέσω ενός νέου που θα επιστρέψει η OpenExeConfiguration.

    Ένα νομίζω ιδιαίτερα χρήσιμο χαρακτηριστικό είναι το ότι η OpenExeConfiguration έχει ένα overload που πέρνει σαν παράμετρο το όνομα του αρχείου με τα settings, συνεπώς δεν είναι ανάγκη να "στοιβάζονται" όλα τα settings στο app.exe.config.

     


    The fact that the program works is irrelevant.
  •  02-12-2005, 10:39 7494 σε απάντηση της 7487

    Απ: .NET 2.0 Configuration Classes

    Σε .NET 1.1 για να αναγκάσεις την εφαρμογή να ξαναδιαβάσει το app.config μπορείς να κάνεις την παρακάτω "βρωμιά":



    using System.Reflection;
    ...
    FieldInfo fi1 = typeof(System.Configuration.ConfigurationSettings).GetField("_configurationInitialized", BindingFlags.Static|BindingFlags.NonPublic);
    fi1.SetValue(null, false);
    FieldInfo fi2 = typeof(System.Configuration.ConfigurationSettings).GetField("_configSystem", BindingFlags.Static|BindingFlags.NonPublic);
    fi2.SetValue(null, null);

     


    Νατάσα Μανουσοπούλου
  •  02-12-2005, 10:51 7496 σε απάντηση της 7494

    Απ: .NET 2.0 Configuration Classes

    Τρελή χακεριά!!!

    Πάντως φαίνεται ότι οι νέες Configuration κλάσεις είναι the way to go. Στο Enterprise Library για το .ΝΕΤ 2.0 έχει καταργηθεί το Configuration Application Block εξαιτίας των νέων configuration κλάσεων.

     


    The fact that the program works is irrelevant.
  •  02-12-2005, 13:10 7502 σε απάντηση της 7487

    Απ: .NET 2.0 Configuration Classes

    Οι αλλαγές που γίνονται μέσω του ConfigurationManager γράφονται κατευθείαν στο σκληρό χωρίς να τροποποιούν τις τιμές που έχουν φορτωθεί. Πρέπει να καλέσεις τη μέθοδο RefreshSection για να ξαναφορτωθεί το section το οποίο τροποποίησες. Το documentation του RefreshSection έχει ένα παράδειγμα όπου ανοίγει ένα config αρχείο με την OpenExeConfiguration, κάνει τροποποιήσεις και τις σώζει με τη Save και τέλος τις φορτώνει στη μνήμη με τη RefreshSection.



    // Set appSettings.
    static void SetAppSettings(bool refresh)
    {
        // Get the machine.config file.
        System.Configuration.Configuration config =
                ConfigurationManager.OpenExeConfiguration(
                ConfigurationUserLevel.None);

        int appStgCnt = ConfigurationManager.AppSettings.Count;
        string asName = "AppSetting" + appStgCnt.ToString();

        config.AppSettings.Settings.Add(asName,
            DateTime.Now.ToLongDateString() + " " +
            DateTime.Now.ToLongTimeString());

       
        // Save the configuration file.
        config.Save(ConfigurationSaveMode.Modified);

        // Refresh the appSettings section so the secction
        // is read from the disk and not from the cache when
        // requested, next time.
        if (refresh)
            ConfigurationManager.RefreshSection("AppSettings");

        GetAppSettings();
    }


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  02-12-2005, 13:17 7503 σε απάντηση της 7502

    Απ: .NET 2.0 Configuration Classes

    Γλούπ! Surprise [:O] Μου είχε ξεφύγει η RefreshSection method!


    Vir prudens non contra ventum mingit
  •  02-12-2005, 14:33 7510 σε απάντηση της 7503

    Απ: .NET 2.0 Configuration Classes

    Απ'ότι φαίνεται η RefreshSection είναι απαραίτητη μόνο όταν χρησιμοποιείς την κλάση ConfigurationManager. Στο παράδειγμα της RefreshSection, πριν την κλήση στη RefreshSection ισχύουν τα παρακάτω που δείχνουν ότι οι αλλαγές που έγιναν δεν είναι ορατές στις ρουτίνες της κλάσης ConfigurationManager, ενώ είναι ορατές στην κλάση Configuration ακόμα και αν χρησιμοποιήσουμε ένα νέο Configuration object. Επίσης οι δοκιμές που έκανα με τις κλάσεις για το custom section δείχνουν ότι οι αλλαγές είναι άμεσα ορατές εφόσον δουλεύουμε με ένα Configuration object.

    Debug.Assert(appStgCnt == ConfigurationManager.AppSettings.Count);
    Debug.Assert(appStgCnt+1 == config.AppSettings.Settings.Count);
    Configuration config2 = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    Debug.Assert(appStgCnt+1 == config2.AppSettings.Settings.Count);

     


    The fact that the program works is irrelevant.
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems