domenica 21 agosto 2011

Valori di configurazioni di SharePoint (Best Practices)

Ogni sviluppatore ASP.NET è abituato a scrivere i valori configurabili nel file web.config per orientare la logica di programmazione in fase di runtime. Questa pratica viene utilizzata per memorizzare informazioni  ad esempio, servizi web, DB, ecc,in modo da avere informazioni a runtime.

Queste è una buona norma, ma se si volessoro cambiare delle informazioni inerenti solo al proprio sistema, senza alterare il comportamento di altri sistemi che usano lo stesso web.config

Ci vogliono due componenti:

    * Un documento XML (conservati in un luogo noto - una libreria di documenti è l'ideale) per memorizzare le impostazioni di configurazione
    * Una classe di cache, e quindi recuperare i valori in fase di runtime

Abbastanza semplice, eh? Ecco un esempio di ciò che il documento XML dovrebbe essere scritto (Noterete che sembra identico al nodo <appSettings> in un file web.config standard):

Code (XML):

<?xml version="1.0" encoding="utf-8"?>
<appSettings>
  <add key="FeedCacheTime" value="300" />
  <add key="DataInProcessId" value="92" />
  <add key="BuyoutThreshold" value="42" />
</appSettings>

Ed ecco il codice per il recupero dei valori in fase di esecuzione (si prega di notare in cui si sono per la fornitura in cui memorizzare il documento di configurazione XML creato nel passaggio precedente):

Code (c#):

using System;
using System.Collections.Specialized;
using System.Configuration;
using System.Xml;
using Microsoft.SharePoint;

namespace Utilities
{
    public static class CustomConfigurationManager
    {
        private static NameValueCollection _configurationItems;

        static CustomConfigurationManager()
        {
            LoadConfiguration();
        }

        private static void LoadConfiguration()
        {
            XmlDocument configurationDocument = new XmlDocument();
           
            string portalUri = string.Empty;
            string relativeUrl = string.Empty;
            string requestUrl = string.Empty;
            string xmlString = string.Empty;

            SPSecurity.CodeToRunElevated secureCode = null;
            
            if (secureCode == null)
            {
                secureCode = delegate
                {
                    portalUri = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority).ToLower();
                    relativeUrl = GetRelativeUrl(URL TO CONFIGURATION XML FILE);
                    requestUrl = portalUri + relativeUrl;

                    using (SPWeb web = new SPSite(requestUrl).OpenWeb())
                    {
                        Uri uri = new Uri(requestUrl);
                        SPFile file = web.GetFile(uri.AbsolutePath);
                       
                        if (file != null)
                        {
                            byte[] bytes = file.OpenBinary();
                            xmlString = Encoding.ASCII.GetString(bytes);
                            bytes = null;
                            configurationDocument.LoadXml(xmlString);
                        }
                        else
                        {
                            xmlString = string.Empty;
                        }
                    }
                };
            }
            SPSecurity.RunWithElevatedPrivileges(secureCode);

            LoadAppSettingsCollection(configurationDocument);
        }

        private static void LoadAppSettingsCollection(XmlDocument configurationDocument)
        {
            _configurationItems = new NameValueCollection();

            XmlNodeList configNodes = configurationDocument.GetElementsByTagName("add");
           
            foreach (XmlNode node in configNodes)
            {
                string key = null;
                string value = null;

                if (!string.IsNullOrEmpty(node.Attributes["key"].Value))
                {
                    key = node.Attributes["key"].Value;
                }

                if (!string.IsNullOrEmpty(node.Attributes["value"].Value))
                {
                    value = node.Attributes["value"].Value;
                }

                if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
                {
                    _configurationItems.Add(key, value);
                }
            }
        }

        private static string GetRelativeUrl(string url)
        {
            StringBuilder builder = new StringBuilder(url.ToLower());
            if (url.ToLower().IndexOf("https://") > -1)
            {
                builder.Replace("https://", string.Empty);
                builder.Remove(0, builder.ToString().IndexOf("/"));
            }
            else if (url.ToLower().IndexOf("http://") > -1)
            {
                builder.Replace("http://", string.Empty);
                builder.Remove(0, builder.ToString().IndexOf("/"));
            }
            return builder.ToString();
        }

        public static NameValueCollection AppSettings
        {
            get { return _configurationItems; }
        }
    }
}

Per accedere ai dati di configurazione si fa in questo modo:

Code (c#):

string feedCacheTime = Utilities.CustomConfigurationManager.AppSettings["FeedCacheTime"];

 1. La chiamata alla configurazione è quasi identica a ottenere fuori del file web.config.
 2. Il file di configurazione è caricato solo una volta per ogni sessione di IIS, in modo da non avere la testa di un sacco di chiamate alla libreria di documenti di configurazione, né si perde tempo in attesa di caricare qualcosa che non cambierà molto spesso.
 3. In questo modo solo il proprio sitema puo vedere le modifche (buona pratica di incapsulamento)
 4. Non ci si deve preoccupare di cambiamenti di informazioni del web.config dovute a esigenze di altri.

Nessun commento:

Posta un commento