Καλησπέρα σε όλους,
Από όταν ξεκίνησα να γράφω Web εφαρμογές με ASP.NET είχα πάντα ένα
άγχος για το που να τοποθετώ όλες τις μεταβλητές - αντικείμενα που
έπρεπε να είναι προσβάσιμα από οποιοδήποτε κομμάτι κώδικα, π.χ. XML
configuration αρχεία, βασικά Datasets, instances αντικειμένων πρόσβασης
στη ΒΔ κτλ κτλ...
Μια πρώτη επιλογή θα ήταν στο
Application object, αλλά τότε έχανα τη
δυνατότητα να ανανεωθεί αυτόματα κάτι όταν αλλάζει. Για αυτό το λόγο
είναι σκόπιμη η χρήση του
Cache object αλλά στο Cache δεν μπορεί κανείς
να σου εγγυηθεί ότι όταν εισάγεις κάτι αυτό θα βρίσκεται εκεί εσαεί
(εντάξει μπορείς να του βάλεις υψηλή σημαντικότητα αλλά... you get the
point).
Σε κάποιο project έλυσα αυτό το θέμα υλοποιώντας μια κλάση που
κληρονομούσε την
System.Web.UI.Page. Σε αυτή
την κλάση υλοποίησα μεθόδους ή Properties που μου επέστρεφαν το
αντικείμενο που ζητούσα. Κατόπιν έβαλα όλες τις σελίδες τις εφαρμογής
να κληρονομούν αυτή τη σελίδα και έτσι βουαλά... είχα τη δυνατότητα από
όλα τα σημεία του κώδικα να έχω αυτό που θέλω. Αν ήμουν π.χ. στο
CodeBehind μιας φόρμας, έκανα cast το αντικείμενο
this στην γονική κλάση και καλούσα την κατάλληλη
μέθοδο. Αν ήμουν στον κώδικα ενός User Object ή και Custom Object
χρησιμοποιούσα το αντικείμενο
Page, έκανα
πάλι τα cast μου και τσουπ... μια χαρά.
Πάλι όμως δεν ήμουν ικανοποιημένος. Κάτι δε μου πήγαινε (ήξερα ότι δεν
είναι αυτός ο λόγος για τον οποίο υπάρχει η κληρονομικότητα
). Και
έτσι σε ένα επόμενο project μου ήρθε η φαεινή ιδέα
, να χρησιμοποιήσω
για αυτό το σκοπό το Global.asax (δηλαδή την κλάση Global που υπάρχει
σε κάθε Web Project). Για του λόγου το αληθές, παραθέτω ένα property
που υλοποίησα στην κλάση Global εκείνου του project :
internal XmlDocument Skins {
get {
XmlDocument x = null;
if (this.Context.Cache["Skins"] == null) {
string strFile =
Server.MapPath("/context/config/application/skins.xml");
x = new XmlDocument();
x.Load(strFile);
this.Context.Cache.Insert("Skins", x, new
System.Web.Caching.CacheDependency(strFile));
}
else x = (XmlDocument) this.Context.Cache["Skins"];
return x;
}
set {
string strFile =
Server.MapPath("/context/config/application/skins.xml");
value.Save(strFile);
}
}
Εντάξει, το έκαψα και λίγο αφού έβαλα μέχρι και να κάνει save το αρχείο
από το property αλλά τη γενική ιδέα την έχετε. Φυσικά το instance του
κλάσης Global είναι προσβάσιμο από οποιαδήποτε Page κλάση, User Control
ή Custom Control μέσω του
ApplicationInstance. Έτσι για να πάρω το skins.xml
σε κάποια φόρμα μου έγραφα απλά (ok, το παραδέχομαι, δεν είναι ακριβώς απλό αλλά είναι λειτουργικό):
XmlDocument x = ((Global)this.Context.ApplicationInstance).Skins;
Όλα τα παραπάνω τα έγραψα για να καταλήξω στα επόμενα ερωτήματα :
- Βρίσκετε κάποιο σφάλμα σε αυτή την πρακτική; Μήπως υπάρχει κάτι που έχω παραβλέψει;
- Ασχέτως της απάντησης στο 1 θα ήθελα να μου πείτε κάποιες
προτάσεις και λύσεις που χρησιμοποιείτε εσείς ως πιο έμπειροι
προγραμματιστές για την επίλυση αυτού του προβλήματος.
Γενικώς είμαι αυτοδίδακτος στο .NET και θα ήθελα να ακούσω μερικές
προτάσεις για αυτό το θέμα που κατά πάσα πιθανότητα δεν θα μου είχαν
ποτέ περάσει από το μυαλό...
Στερνή μου γνώση να σε είχα πρώτα...