Social Icons

miércoles, 3 de abril de 2013

Compartiendo Datos Entre Front Ends con Thread Safe Web Properties

¿Te acuerdas en los viejos tiempos cuando solo tenías un frontend? ¿Te acuerdas cuando pensabes que era complicado?

Las cosas han cambiado y ahora para casi cualquier entorno de producción tienes unos cuantos frontents y está bien, el rendimiento mejora y, con SharePoint, es fácil meter uno más si te parece que vas corto pero también ha llevado algunas tareas a un nuevo nivel de complejidad.

Hay software por ahí como AppFabric que te permite persistir datos y compartirlos entre todos tus servidores. AppFabric es bueno pero... ¿Vas a instalar y configurar todo en todos los servers para compartir un string de 10 caracteres?

Bueno, no te hace falta. Puedes usar las Web Properties de SharePoint para hacerlo. Son rápidas de leer, de escribir, de programar y no tienes que configurar nada.

Las Web Properties de SharePoint son un poco raritas a la hora de usarlas, especialmente cuando las usas en un proceso multi hilo, pero estos wrappers pueden ahorraros algún tiempo. (Yo los he usado en un par de escenarios y funcionan, pero no puedo asegurar que sean completamente seguros)

static object PropertyWriteLock = new object();

/// <summary>
/// Sets a web property to a given value. This method is thread safe.
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <param name="Value">Value to set the property to</param>
public static void SetWebProperty(this SPWeb Web, string Key, string Value)
{
    Key = Key.ToLower();
    lock (PropertyWriteLock) //It's better to have a lock just for the key we are working with.
    {
        if (GetWebPropertyThreadSafe(Web, Key) != Value)
        {
            Web.Properties[Key] = Value;

            Web.Properties.Update();
        }
    }
}

/// <summary>
/// Returns the web property with the given key. This method is thread safe.
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <returns>Returns null if not found</returns>
public static string GetWebPropertyThreadSafe(this SPWeb Web, string Key)
{
    Key = Key.ToLower();
    using (SPSite site = new SPSite(Web.Site.ID))
    {
        using (SPWeb newWeb = site.OpenWeb(Web.ID))
        {
            return newWeb.GetWebProperty(Key);
        }
    }
}

/// <summary>
/// Returns the web property with the given key.
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <returns>Returns null if not found</returns>
public static string GetWebProperty(this SPWeb Web, string Key)
{
    Key = Key.ToLower();

    return Web.Properties[Key];
}

/// <summary>
/// Removes the web property from the web
/// </summary>
/// <param name="Key">The Key for the web property (case insensitive)</param>
/// <remarks>The web property will remain there but set to null.</remarks>
public static void RemoveWebProperty(this SPWeb Web, string Key)
{
    if (Web.Properties.ContainsKey(Key))
        Web.Properties.Remove(Key);

    Web.Properties.Update();

    if (Web.AllProperties.ContainsKey(Key))
        Web.AllProperties.Remove(Key);

    Web.Update();
}

Esto ha simplificado algunas partes de la aplicación un montón y, voy a decirlo otra vez, es rápido.

Pruébalo y me cuentas.

No hay comentarios: