Compartir a través de


Descarga de código de la Galería de código de MSDN
Examinar el código en línea

Cutting Edge

Administración dinámica entrega el contenido de Silverlight, parte 2

Dino Esposito

Contenido

Motivación para una caché permanente
Fundamentos de almacenamiento aislado
API de almacenamiento aislado
Crear una caché permanente de los paquetes
Las directivas de caducidad
Poner todos los equipo
Algunas notas finales

El mes pasado hablé cómo servir algún contenido generado de forma dinámica una aplicación de Silverlight en el inicio e incluso en un escenario a petición. Muchos ejemplos existen hay para mostrarle cómo utilizar la clase de cliente Web y su modelo de llamada asincrónica para descargar un recurso basado en URL. En concreto, me centré en lo que se tarda en descargar un paquete XAP que incluya XAML y código administrado (consulte la Entrega de enero de 2009 de Cutting Edge .

La idea básica es que se descargue una secuencia en ZIP y, a continuación, extraer cualquier ensamblado que necesita. A continuación, crear instancias cualquier clase necesita que está contenida en el ensamblado. La clase es un control de usuario XAML, una parte completa de un árbol visual de XAML, que se pueden anexar a los marcadores de posición en el modelo de objeto de documento (DOM) XAML actual.

El explorador, los recursos XAP descargados son totalmente indistinguishable desde cualquier otro tipo de recurso. Por lo tanto, el explorador almacena en caché un paquete XAP al igual que cualquier otro recurso descargado. Este mecanismo integrado ofrece un primer nivel de optimización que guarda repite viajes de ida y vuelta para obtener el mismo paquete una y otra vez. La clase de cliente Web, el núcleo del componente Descargador descrito en la columna del mes pasado, se basa en motor de conectividad el explorador y no descargar los recursos disponibles localmente y no ha caducado.

Al final del día, tiene un componente Descargador para aplazar la carga de los paquetes externos que quizá deba. Además, también tiene libre caché funciones para los recursos dinámicamente descargados. Entre otras cosas, es posible que desea agregar una caché local permanente de los paquetes que también pueda tratar cambios dinámicos al árbol visual. Veamos cómo lograr esto.

Motivación para una caché permanente

Cuando trata de contenido de Silverlight dinámico, hay dos aspectos principales a través del cual desee tener algún control más.

El primero es la directiva de caducidad del contenido descargado. Es posible que desea controlar exactamente cuando un determinado paquete caduca y debe descargarse de nuevo. Además, es posible que desea vincular la caducidad a algún evento externo such as una acción de usuario concreto o los cambios a otros recursos almacenados en caché. Si sabe cómo funciona la caché de ASP.NET, sabe qué me refiero.

La caché de ASP.NET, de hecho, le permite almacenar datos en memoria caché y proporcionar su propia directiva de caducidad de cada elemento almacenado en caché, de acuerdo con los cambios en el archivo, fecha y hora, o incluso cambios a otros elementos almacenados en caché. No existe un motor similar en Silverlight 2, pero aplicaciones grandes, dinámicas y altamente personalizables podrían obtener beneficios significativos de él.

El aspecto de segundo de caché de recursos de Silverlight estándar que desea cambiar considera la exposición de los paquetes a la actividad del usuario. En otras palabras, cualquier paquete XAP guardado en caché del explorador es en la mercy del usuario. Si el usuario borra la caché que actúa de interfaz del explorador, todos los paquetes XAP se perderán inevitablemente.

Una caché permanente administrado de la aplicación trata dos problemas. Paquetes XAP almacenados en esta memoria caché permanente no podrían verse afectados por el usuario borrar la caché del explorador. Para almacenar permanentemente los paquetes de Silverlight XAP, necesita obtener acceso al sistema de archivos local. Por motivos de seguridad, Silverlight no permite las aplicaciones de acceso al sistema completo de archivos local. Sin embargo, la API de almacenamiento aislado es aquí ayudar a. Para obtener más información sobre la seguridad de Silverlight, consulte" CLR Inside Out: seguridad en Silverlight 2 ."

Fundamentos de almacenamiento aislado

Almacenamiento aislado no se creó específicamente para Silverlight. Almacenamiento aislado ha formado parte de Microsoft .NET Framework desde la versión 1.0. Dirigidos a las aplicaciones de confianza parcial, el almacenamiento aislado permite tales aplicaciones para almacenar datos en el equipo local en sentido completo de cualquier directiva de seguridad continua. Un clásico de plena confianza aplicación .NET no tiene probablemente nunca atraviesan la capa de almacenamiento aislado para guardar sus propia datos es necesario, pero para una aplicación con confianza parcial, el almacenamiento aislado es la única opción para guardar los datos en el cliente.

Desde una perspectiva Silverlight, el almacenamiento aislado es una herramienta eficaz y la forma sólo es posible para que persistan relativamente grandes fragmentos de datos de una manera entre exploradores y sin ninguna de las restricciones que afecten a, por ejemplo, cookies HTTP. Es importante comprender este punto: de Silverlight, el almacenamiento aislado es la posibilidad sólo tendrá que almacenar datos en caché en el equipo local. Si una aplicación de Silverlight necesita guardar algunos datos, cualquier tipo de datos, localmente, a continuación, puede hacerlo sólo a través de almacenamiento aislado. Además, con el almacenamiento aislado cada aplicación puede mantener sus propia datos aislados de otras aplicaciones o de las demás aplicaciones fuera del sitio.

Si desea una introducción general, orientado a .NET al almacenamiento aislado y sus escenarios de uso más comunes, debe leer el Guide .NET framework Developer 'S en el almacenamiento aislado . El artículo menciona un par de situaciones donde mediante el almacenamiento aislado no es apropiado. En concreto, las instrucciones diga que debería no utilizar el almacenamiento aislado para almacenar confidencial configuración de datos, el código o la configuración (distintos de las preferencias del usuario). Tales instrucciones provienen de un conocimiento general de seguridad y no implican necesariamente los peligros inherentes en el uso del almacenamiento aislado.

¿Por lo tanto, puede con seguridad almacenar en paquetes XAP que se descarga en el almacenamiento aislado de Silverlight? En Silverlight, a diferencia de en el CLR de escritorio, cualquier fragmento de código ejecutable que no es de es confianza de forma predeterminada y no se permite invocar métodos críticos o elevar los privilegios de la pila de llamadas. De Silverlight, cualquier código que almacén para la ejecución posterior podrán hacer nada peligroso. Esto es no es más arriesgado que ejecutar cualquier otro fragmento de código de Silverlight. Mediante la creación de una caché permanente de los paquetes de Silverlight, acabará almacenamiento local de un segmento de la aplicación de Silverlight que están ejecutando consciously.

En Silverlight, la función de almacenamiento aislado es análoga, lo que respecta a persistencia, a la función de las cookies HTTP en aplicaciones Web clásicos. En Silverlight, es preciso consultar al almacenamiento aislado como un conjunto de cookies más grandes que puede contener cualquier tipo de datos, incluido el código ejecutable. En este caso, sin embargo, el núcleo de Silverlight CLR proporciona protección. Según en el modelo de seguridad de Silverlight, de hecho, el núcleo CLR producirá una excepción cada vez que el código de la aplicación quiere ejecutar métodos críticos. A diferencia de cookies HTTP, el almacenamiento aislado en Silverlight no está vinculado a E/s de red y contenido no se transmite con solicitudes.

Datos en el almacenamiento aislado está aislados por aplicación y ninguna otra aplicación de Silverlight puede tener acceso el almacén. Los datos se almacenan en el sistema de archivos local, sin embargo, por lo que un administrador del equipo es ciertamente, capaz de tener acceso a ella.

De nuevo, el modelo general no es muy diferente de lo que ocurre con las cookies HTTP. Un administrador puede buscar siempre y incluso modificar el contenido de las cookies. Si es necesario en el contexto, puede utilizar cifrado para agregar otro nivel de protección de datos.

Si preocupa aún tener algún código ejecutable descargado muestra alrededor de su equipo, debe actualizar la descripción del modelo de seguridad de Silverlight de. En resumen, el núcleo de Silverlight CLR producirá una excepción que cualquier código de aplicación tiempo intenta ejecutar un método crítico. En la biblioteca de clases de Silverlight base (BCL), métodos y clases que realizan operaciones que requieren privilegios de altos se marcan con un atributo de SecurityCritical especial. Tenga en cuenta que es el caso de la mayor parte del contenido del espacio de nombres de System.IO.

La seguridad de Silverlight reconoce que algunas clases de plataforma que necesita colocar seguras llamadas a métodos críticas. Como las clases y métodos, a continuación, se marcan con el atributo SecuritySafeCritical. Éste es el caso con las clases de la API de System.IO.IsolatedStorage (consulte la figura 1 ). El punto clave sobre la seguridad de Silverlight es que nunca se puede marcar no fragmento de código de aplicación con el atributo SecurityCritical o SecuritySafeCritical. Este atributo está reservado para las clases de ensamblados firmado digitalmente por Microsoft y cargan en la memoria desde el directorio de instalación de Silverlight.

fig01.gif

Figura 1 de exploración dentro del API de almacenamiento aislado

Como puede ver, incluso en las circunstancias muy una pena (y poco probable) que algún chico malintencionado penetrates el equipo y reemplaza descargan el contenido de Silverlight, los daños está limitado a las operaciones habituales ejecutables en modo transparente.

API de almacenamiento aislado

Las BCL Silverlight viene con su propia implementación del almacenamiento aislado que se tailor-made para el escenario de Web. Almacenamiento aislado proporciona acceso a un subárbol del sistema de archivos totalmente local y ningún método o propiedad permite nunca ejecutar código para averiguar dónde el almacén de archivo se encuentra físicamente en el equipo del usuario. Una aplicación de Silverlight no se permite utilizar rutas de sistema de archivo absoluta a través de almacenamiento aislado. Del mismo modo, la información de unidad no está disponible y no es compatible y el mismo se aplica a rutas relativas que contengan puntos suspensivos como ésta:

\..\..\myfile.txt 

El subárbol de almacenamiento aislado raíz en una carpeta que se encuentra en la ruta de acceso de usuario actual. Por ejemplo, en Windows Vista, la raíz de la carpeta de almacenamiento aislado se encuentra en el directorio de usuarios.

Una aplicación de Silverlight obtiene acceso al punto de entrada el almacenamiento aislado específico de la aplicación mediante una llamada de método:

using (IsolatedStorageFile iso = 
       IsolatedStorageFile.GetUserStoreForApplication()) 
{
  ...
}

El método estático que GetUserStoreForApplication devuelve el símbolo (token) se utiliza para cualquier acceso adicional al almacenamiento aislado. Cuando se realiza la primera llamada a GetUserStoreForApplication, se crea el subárbol específico de la aplicación, si no existe ya.

El almacenamiento aislado de Silverlight API proporciona clases para trabajar con archivos y directorios en el subárbol de sistema de archivos protegidos. Afortunadamente, la lista de clases que necesita saber es bastante corta; los enumerados en la figura 2 encontrará.

fig02.gif

En la clase IsolatedStorageFile, hay una serie de métodos para crear y eliminar archivos y directorios, para comprobar la presencia de los archivos y directorios y para leer y escribir archivos nuevos. Emplear secuencias para trabajar con archivos. Opcionalmente, puede ajustar arriba secuencias con los lectores de secuencia, que son mucho más cómodos objetos para trabajar con. la figura 3 muestra un ejemplo breve de cómo crear un archivo de almacenamiento aislado utilizando un escritor de secuencia.

La figura 3 crear un archivo de almacenamiento aislado

using (IsolatedStorageFile iso = 
      IsolatedStorageFile.GetUserStoreForApplication())
{
    // Open or create the low level stream
    IsolatedStorageFileStream fileStream;
    fileStream = new IsolatedStorageFileStream(fileName, 
        FileMode.OpenOrCreate, iso);

    // Encapsulate the raw stream in a more convenient writer
    StreamWriter writer = new StreamWriter(stream);

    // Write some data
    writer.Write(DateTime.Now.ToString());

    // Clean up
    writer.Close();
    stream.Close();
}

Una vez que se ajusta una secuencia de bajo nivel en un escritor de secuencia más adecuado o lector, el código que se utiliza para escribir o leer algunos datos es casi idéntico en el código que deberá utilizar en una aplicación .NET clásica. Veamos cómo aprovechar el API de almacenamiento aislado para guardar cualquier paquete XAP descargado localmente y volverlo a cargar posteriormente.

Crear una caché permanente de los paquetes

En la columna del mes pasado, utiliza una clase contenedora de Descargador para ocultar parte el código repetitivo que debe descargar un paquete XAP y extraer los ensamblados y otros recursos. La clase Descargador, sin embargo, no es sólo una clase auxiliar. Conceptualmente, representa una parte realista de lógica que es posible que desee aislar del resto del código de aplicación de una serie de motivos.

La razón de primera que springs a la cuenta es testability. Al exponer la funcionalidad de un componente Descargador a través de una interfaz, obtendrá la posibilidad de forma rápida y efectiva simulacros el Descargador para fines de prueba. Además, un representa interfaz la herramienta aprovechar para reemplazar un Descargador más sencillo con una más sofisticados uno que, quizás, sólo ocurre admitir el almacenamiento en caché de paquete. la figura 4 muestra la arquitectura del que debe objetivo de diseño.

fig04.gif

La figura 4 el componente Descargador y el resto de la aplicación

fig05.gif

La figura 5 extraer una interfaz

En el código de origen del mes pasado, la clase Descargador era un fragmento de código monolítica. Para un diseño más flexible, vamos a extraer una interfaz fuera de ella. Como se muestra la figura 5 , Visual Studio tiene un menú contextual que, aunque no lo enriquecido que el de las herramientas de refactorización comerciales, ofrece ayuda con la extracción de una interfaz fuera de una clase.

Ahora que el núcleo de la aplicación de Silverlight se comunica con la interfaz IDownloader, debe ir la lógica para el paquete de almacenamiento en caché sólo dentro de la clase Descargador real:

interface IDownloader
{
    void LoadPackage(string xapUrl, string asm, string cls);
    event EventHandler<Samples.XapEventArgs> XapDownloaded;
}

En concreto, el método LoadPackage se se volver a escribir para incorporar la lógica que podría comprobar la existencia del paquete XAP especificado en el almacenamiento aislado y descargar, de Internet en caso contrario. Figura 6 muestra una sección grande del código de la clase Descargador. El método primero intenta obtener la secuencia para el paquete XAP desde la caché interna. Si este intento falla, el método continúa y descarga el paquete del servidor host. (Esto es sólo lo que explicará detalladamente el mes pasado).

Compatibilidad de caché de la figura 6 para el componente Descargador

public void LoadPackage(string xap, string asm, string cls)
{
    // Cache data within the class
    Initialize(xap, asm, cls, PackageContent.ClassFromAssembly);

    // Have a look in the cache
    Stream xapStream = LookupCacheForPackage();
    if (xapStream == null)
        StartDownload();
    else
    {
        // Process and extract resources
        FindClassFromAssembly(xapStream);
    }
}

protected Stream LookupCacheForPackage()
{
    // Look up the XAP package for the assembly.
    // Assuming the XAP URL is a file name with no HTTP information
    string xapFile = m_data.XapName;

    return DownloadCache.Load(xapFile);
}

protected void StartDownload()
{
    Uri address = new Uri(m_data.XapName, UriKind.RelativeOrAbsolute);
    WebClient client = new WebClient();

    switch (m_data.ActionRequired)
    {
        case PackageContent.ClassFromAssembly:
            client.OpenReadCompleted += 
                new OpenReadCompletedEventHandler(OnCompleted);
            break;
        default:
            return;
    }
    client.OpenReadAsync(address);
}

private void OnCompleted(object sender, OpenReadCompletedEventArgs e)
{
    // Handler registered at the application level?
    if (XapDownloaded == null)
        return;

    if (e.Error != null)
        return;

    // Save to the cache
    DownloadCache.Add(m_data.XapName, e.Result);

    // Process and extract resources
    FindClassFromAssembly(e.Result);
}

private void FindClassFromAssembly(Stream content)
{
    // Load a particular assembly from XAP
    Assembly a = GetAssemblyFromPackage(m_data.AssemblyName, content);

    // Get an instance of the specified user control class
    object page = a.CreateInstance(m_data.ClassName);

    // Fire the event
    XapEventArgs args = new XapEventArgs();
    args.DownloadedContent = page as UserControl;
    XapDownloaded(this, args);
}

En Silverlight, descarga es un proceso asincrónico, por lo que el método interno StartDownload provoca un evento de "completado" cuando el paquete está totalmente disponible en el cliente. El controlador de eventos en primer lugar guarda el contenido de la secuencia de paquete XAP en un archivo local y, a continuación, extrae los recursos de él. Tenga en cuenta que en el código de ejemplo estoy sólo extraer los ensamblados; almacenamiento en caché las capacidades para cualquier otro tipo de recurso de como XAML para animaciones, imágenes o otros archivos auxiliares en un componente más general que es posible que desea extender.

El método de LoadPackage de la clase Descargador sirve para descargar controles Silverlight­user para insertar en el árbol de XAML actual. Puesto que el paquete XAP es un contenedor multi-file, tendrá que especificar qué ensamblado contiene el control de usuario y el nombre de la clase. El código en la figura 6 simplemente extrae el ensamblado especificado el paquete, lo carga en el AppDomain actual y, a continuación, crea una instancia de la clase contenida especificada.

¿Qué ocurre si el ensamblado tiene algunas dependencias? Sólo el código de la figura 6 no cubre este escenario. Como resultado, si el ensamblado se pasa como argumento a LoadPackage tiene una dependencia en otro ensamblado (incluso en el mismo paquete XAP), recibe una excepción tan pronto como el flujo de ejecución alcanza una clase en el ensamblado de dependencia. El punto es que todos los ensamblados en el paquete se deben cargados en memoria. Para que esto suceda, que necesite tener acceso al archivo de manifiesto correspondiente, lea acerca de los ensamblados implementados y procesarlas. Figura 7 muestra cómo cargar en memoria todos los ensamblados a los que se hace referencia en el archivo de manifiesto.

La figura 7 carga todos los ensamblados en el manifiesto

private Assembly GetAssemblyFromPackage(
     string assemblyName, Stream xapStream)
{
    // Local variables
    StreamResourceInfo resPackage = null;
    StreamResourceInfo resAssembly = null;

    // Initialize
    Uri assemblyUri = new Uri(assemblyName, UriKind.Relative);
    resPackage = new StreamResourceInfo(xapStream, null);
    resAssembly = Application.GetResourceStream(
                              resPackage, assemblyUri);

    // Extract the primary assembly and load into the AppDomain 
    AssemblyPart part = new AssemblyPart();
    Assembly a = part.Load(resAssembly.Stream);

    // Load other assemblies (dependencies) from manifest
    Uri manifestUri = new Uri("AppManifest.xaml", UriKind.Relative);
    Stream manifestStream = Application.GetResourceStream(
        resPackage, manifestUri).Stream; 
    string manifest = new StreamReader(manifestStream).ReadToEnd();

    // Parse the manifest to get the list of referenced assemblies
    List<AssemblyPart> parts = ManifestHelper.GetDeploymentParts(manifest);

    foreach (AssemblyPart ap in parts)  
    {
        // Skip over primary assembly (already processed) 
        if (!ap.Source.ToLower().Equals(assemblyName))
        {
            StreamResourceInfo sri = null;
            sri = Application.GetResourceStream(
                resPackage, new Uri(ap.Source, UriKind.Relative));
            ap.Load(sri.Stream);
        }
    }

    // Close stream and returns
    xapStream.Close();
    return a;
}

El archivo de manifiesto es un archivo XML, tal como se muestra aquí:

<Deployment EntryPointAssembly="More" EntryPointType="More.App" 
            RuntimeVersion="2.0.31005.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="More" Source="More.dll" />
    <AssemblyPart x:Name="TestLib" Source="TestLib.dll" />
  </Deployment.Parts>
</Deployment> 

Para analizar este archivo, puede utilizar con LINQ para XML. El código fuente contiene una clase de ManifestHelper ejemplo con un método que devuelve una lista de objetos AssemblyPart (consulte la figura 8 ). Es importante recordar que en versiones beta de Silverlight 2, puede utilizar la clase XamlReader para analizar el archivo de manifiesto a un objeto de implementación:

// This code throws in Silverlight 2 RTM
Deployment deploy = XamlReader.Load(manifest) as Deployment;

Figura 8 análisis del manifiesto con LINQ to XML

public class ManifestHelper
{
   public static List<AssemblyPart> GetDeploymentParts(string manifest)
   {
      XElement deploymentRoot = XDocument.Parse(manifest).Root;
      List<AssemblyPart> parts = 
          (from n in deploymentRoot.Descendants().Elements() 
           select new AssemblyPart() { 
                Source = n.Attribute("Source").Value }
          ).ToList();

          return parts;
   }
}

En la versión de lanzamiento, el objeto de implementación se ha transformado en un singleton y posteriormente, no se puede utilizar para cargar los ensamblados dinámicamente. El código XML en el manifiesto, por tanto, debe analizarse manualmente.

Las directivas de caducidad

Tal y como, por tanto, ahora se ha implementado, la caché de ensamblados es permanente y no hay ninguna manera para el usuario obtenga paquetes actualizados. La solución sólo es posible es que un administrador del equipo busque archivos de almacenamiento aislado para la aplicación y eliminarlos manualmente a través del explorador de Windows.

Veamos qué necesitaría para agregar una directiva de caducidad simple que realiza cualquier archivo XAP en caché obsoleto después de una determinada cantidad de momento después de descargar. El lugar adecuado para establecer una directiva de caducidad es la clase DownloadCache, como en la figura 6 . Cuando se agrega un archivo XAP a la caché, deberá almacenar alguna información sobre el tiempo de descarga. Cuando se obtiene acceso a la caché para recoger un paquete, debe comprobar si el paquete ha caducado (consulte la figura 9 ).

Prueba de la figura 9 de caducidad

public bool IsExpired(string xapFile)
{
    bool expired = true;
    if (m_ItemsIndex.ContainsKey(xapFile))
    {
        DateTime dt = (DateTime)m_ItemsIndex[xapFile];

        // Expires after 1 hour
        expired = dt.AddSeconds(3600) < DateTime.Now;    
        if (expired)
            Remove(xapFile);
    }

    return expired;
}

La implementación de un algoritmo aparentemente simple es hindered por un hecho notable. En Silverlight, no dispone de ninguna forma de acceso a atributos de archivo como la última vez creación o actualización. Esto significa que son responsable de administrar la información de hora. En otras palabras, cuando se agrega un XAP a la caché también crear una entrada en algunos diccionario persistente y personalizado que realiza el seguimiento cuando se ha descargado el paquete. No hace falta decir que esta información debe almacenarse en cierta forma con el almacenamiento aislado. la figura 10 ilustra este concepto.

Figura 10 almacenar descargar detalles en el almacenamiento aislado

public static Stream Load(string file)
{
    IsolatedStorageFile iso;
    iso = IsolatedStorageFile.GetUserStoreForApplication();

    if (!iso.FileExists(file))
    {
        iso.Dispose();
        return null;
    }

    // Check some expiration policy
    CacheIndex m_Index = new CacheIndex();
    if (!m_Index.IsExpired(file))
        return iso.OpenFile(file, FileMode.Open);

    // Force reload
    iso.Dispose();
    return null;
}

CacheIndex es una clase auxiliar que utiliza la configuración de aplicación nativa de Silverlight API para conservar un diccionario de nombres XAP y descargar veces en el almacenamiento aislado. El miembro m_ItemIndex es un objeto Dictionary crear instancia en CacheIndex constructor, como se muestra en la figura 11 .

Figura 11 la clase CacheIndex

public class CacheIndex
{
    private const string XAPCACHENAME = "XapCache";
    private Dictionary<string, object> m_ItemsIndex; 
    public CacheIndex()
    {
      IsolatedStorageSettings iss;
      iss = IsolatedStorageSettings.ApplicationSettings;
      if (iss.Contains(XAPCACHENAME))
         m_ItemsIndex = iss[XAPCACHENAME] as Dictionary<string, object>;
      else
      {
         m_ItemsIndex = new Dictionary<string, object>();
         iss[XAPCACHENAME] = m_ItemsIndex;
         iss.Save();
      }
   }
  ...
}

ApplicationSettings es una característica muy interesante de Silverlight 2. Básicamente consta de un diccionario de cadenas y objeto y automáticamente se lee desde el almacenamiento en la aplicación cargar y guardar en el almacenamiento después del cierre. Automáticamente se conserva cualquier objeto (serializable) agregar al diccionario.

Al crear una entrada XAPCACHENAME en el diccionario, se organizan conservar el contenido del diccionario XAP. El diccionario XAP contiene una entrada para cada paquete descargado emparejada con la hora de la descarga, tal como se observa en Figura 12 . Tenga en cuenta que la API de ApplicationSettings del también ofrece un método de guardar para forzar la persistencia antes de cierre de la aplicación.

Figura 12 agregar descarga de información

public void Add(string xapFile)
{
    m_ItemsIndex[xapFile] = DateTime.Now;
    IsolatedStorageSettings iss;
    iss = IsolatedStorageSettings.ApplicationSettings;
    iss.Save();                
}

public void Remove(string xapFile)
{
    m_ItemsIndex.Remove(xapFile);
    IsolatedStorageSettings iss;
    iss = IsolatedStorageSettings.ApplicationSettings;
    iss.Save();
}

Poner todos los equipo

Todos los cambios y detalles descritos hasta ahora se producen detrás de la cortina de una clase pública, la clase Descargador. Mediante la incorporación de esta clase en la aplicación de Silverlight, obtendrá varios niveles de almacenamiento en caché en una sola captura. Con codificación correcta que puede almacenar en caché descarga los controles de usuario para la duración de la sesión de aplicación. Si descarga el contenido que va a, por ejemplo, un elemento de ficha, puede, a continuación, ocultar y mostrar el elemento de ficha varias veces sin necesidad de descargar el paquete una y otra vez.

Si descarga a través de la clase de cliente Web (como en la columna del mes pasado), pasar a través del motor de explorador y obtener la caché de nivel para el explorador. Cualquier paquete XAP descargado reside en el equipo del usuario hasta que el usuario borra la caché del explorador. Por último, la clase de Descargador que obtendrá en esta columna admite una caché permanente a través de almacenamiento aislado. Esto significa que cada vez que se descarga a través de cliente Web, el paquete XAP también se guarda al almacenamiento local.

La Descargador clase, sin embargo, también ofrece seleccionar el archivo XAP desde el almacenamiento si se puede encontrar un paquete válido. Tenga en cuenta que esto funciona en sesiones de la aplicación. Descargar el paquete una vez, usted trabaja y, a continuación, cerrar la aplicación. Cuando reanude, el paquete se vuelve a cargar del almacenamiento si no ha caducado. ¿Qué ocurre si caduca el paquete? En este caso, el Descargador pasa a través de cliente Web. Pero en este punto, cliente Web sólo puede devolver una copia en caché para el explorador previamente del mismo paquete.

Esto es una decisión de diseño. Para omitir la caché de nivel para el explorador, deberá deshabilitarlo en la solicitud HTTP original, como se describe el mes pasado. Debe almacenar en caché las propiedades en el nivel de página o obtenga el paquete a través de un controlador HTTP que es posible establecer directivas de caducidad con mayor precisión sin afectar a otros recursos que con la página.

Algunas notas finales

Almacenamiento en caché el paquete XAP no significa que el almacenamiento en caché recursos individuales, como archivos DLL, animaciones en XAML, o contenido multimedia. En la implementación actual, los recursos se extraen del paquete XAP cada vez que se utilizan. Sin embargo, esto es un aspecto que puede mejorar aún más en con la clase Descargador. Igualmente, el paquete ofrece un control de usuario pero no hacer un seguimiento de los cambios que puede obligar al usuario en su interfaz de usuario. Seguimiento de cambios dinámicos el árbol de XAML es otro tema y merece un artículo de su propia.

Hay dos formas para tener acceso un sistema de archivos privados de Silverlight en equipo local del usuario. En todos los fragmentos de código para esta columna, utilizó el método GetUserStoreForApplication en la clase IsolatedStorageFile. Este método devuelve un símbolo para tener acceso a una sección del sistema de archivos que está aislado por aplicación, lo que significa que todos y sólo los ensamblados asociados con una aplicación utilizarán el mismo almacén. También puede seleccionar un almacén y compartirla en todas las aplicaciones alojadas en el mismo sitio. En este caso, se obtiene el símbolo (token) a través del método GetUserStoreForSite.

Tenga en cuenta demasiado que almacenamiento local se puede administrar mediante el cuadro de diálogo de configuración de Silverlight (clic con el botón secundario en una aplicación de Silverlight) y incluso deshabilitar por completo. En este caso, al intentar obtener el símbolo (token), se generará una excepción. Una cuota de disco también se aplica al almacenamiento local en cada dominio; su valor predeterminado es 1 MB. Recuerde esto al planear para una caché permanente de Silverlight.

Envíe sus preguntas y comentarios para Dino a dirección cutting@microsoft.com.

Dino Esposito es un arquitecto en IDesign y el coautor de Microsoft .NET: Architecting Applications for the Enterprise (Microsoft Press, 2008). Basándonos en Italia, Dino es un orador frecuente en eventos del sector en todo el mundo. Puede combinar su blog en weblogs.asp. NET/despos.