Using Caching Application Block with Silverlight

Topics: Caching Application Block , Silverlight Integration Pack
Oct 20, 2011 at 8:32 AM

Hi!

I am searching for a simple example to use the Caching Application Block within my Silverlight 5 Application - but i couldn't find anything that I get to work.

The Reference Implementation is a huge Project - I don't know really where to start (eg. can i use it without unity?).

The channel9 demo doesn't tell a lot about setting it up. And other internet ressources are rare.

thanks for any help!!

Oct 23, 2011 at 9:10 AM
Edited Oct 23, 2011 at 9:11 AM

I think the Stock Trader Reference Implementation is currently the best place to look.

To get caching working you will need a XAML file with the configuration information.  In the RI look at:

EntLib for Silverlight - Stock Trader RI\WebApplication\StockTrader.Web\Configuration\StockTraderRI.Silverlight.xaml

This file is in the web project.  If you want to edit it with Intellisense you can copy it into the Silverlight project.

Now in the Silverlight code you will need to download the XAML file and configure the Container.  In the RI there are some helper classes that can make it a
bit complicated (e.g. fetching multiple files and merging them, etc.).  Not that they aren't useful but you can get by without them -- especially just to get an example working.

To configure the container you can use:

 var configUri = new Uri("/cacheConfig.xaml", UriKind.Relative);
 EnterpriseLibraryContainer.ConfigureAsync(configUri);

 In a real app you probably want to check the status:

void OnConfigurationCompleted(object sender, EnterpriseLibraryConfigurationCompletedEventArgs e)
{
    if (!e.ConfiguredSuccessfully)
    {
        throw new InvalidOperationException("Configuration Failed", e.Error);
    }
    // Set configured state
}

void StartEntlibInitialization()
{
    EnterpriseLibraryContainer.EnterpriseLibraryConfigurationCompleted += OnConfigurationCompleted; 

    var configUri = new Uri("/cacheConfig.xaml", UriKind.Relative);
    EnterpriseLibraryContainer.ConfigureAsync(configUri);
}

I hope that gets you started.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com

Oct 24, 2011 at 6:51 PM

Thanks for your answer. This seems to work - yep - but the example loads the configuration asynchron. In the "Enterprise Library 5.0 Silverlight - Documentation.chm" there is a part that describes how to configure the cache directly. I have done this but i cannot get it to work:

configuration.xaml (build-action set to content; located in my SL application in the root):

    <?xml version="1.0" encoding="utf-8"?>
    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                        xmlns:el="http://schemas.microsoft.com/practices/2011/entlib">
      <el:CachingSettings DefaultCache="In-Memory Cache" x:Key="cachingSilverlightConfiguration">
        <el:CachingSettings.Caches>
          <el:InMemoryCacheData ExpirationPollingInterval="00:02:00" Name="In-Memory Cache" />
        </el:CachingSettings.Caches>
      </el:CachingSettings>
    </ResourceDictionary>

And my C# call looks like:

var cache = EnterpriseLibraryContainer.Current.GetInstance<ObjectCache>("In-Memory Cache");

And the Exception says:

Activation error occured while trying to get instance of type ObjectCache, key "In-Memory Cache"

Thanks for any help!

Oct 25, 2011 at 5:31 AM
Edited Oct 25, 2011 at 11:16 PM

It looks like you haven't configured the container.  If you don't want to call to the server to retrieve the configuration (although I think this is preferable) then you need to embed and load the configuration.

e.g.

string stringWithXAMLConfiguration = @"<?xml version=""1.0"" encoding=""utf-8""?>
<el:ConfigurationDictionary xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 
                xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" 
                xmlns:el=""http://schemas.microsoft.com/practices/2011/entlib"">
<el:CachingSettings DefaultCache=""In-Memory Cache"" x:Key=""cachingSilverlightConfiguration"">
    <el:CachingSettings.Caches>
        <el:InMemoryCacheData ExpirationPollingInterval=""00:02:00"" Name=""In-Memory Cache"" />
        <el:IsolatedStorageCacheData MaxSizeInKilobytes=""5120"" PercentOfQuotaUsedBeforeScavenging=""50"" PercentOfQuotaUsedAfterScavenging=""20"" ExpirationPollingInterval=""00:01:00"" Name=""Isolated Storage Cache"" />
    </el:CachingSettings.Caches>
</el:CachingSettings>
</el:ConfigurationDictionary>";

var configDictionary = (IDictionary)XamlReader.Load(stringWithXAMLConfiguration);
var configSource = DictionaryConfigurationSource.FromDictionary(configDictionary);
EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);

 Or if you don't want to have the string in the code but prefer in a XAML file then ensure the XAML file's (e.g. cacheConfig.xaml) Build Action is Embedded Resource and then you can use the following code:

string xaml;
using (Stream s = this.GetType().Assembly.GetManifestResourceStream("SilverlightApplicationCache.cacheConfig.xaml"))
using (StreamReader sr = new StreamReader(s))
{
    xaml = sr.ReadToEnd();
}

var configDictionary = (IDictionary)XamlReader.Load(xaml);
var configSource = DictionaryConfigurationSource.FromDictionary(configDictionary);
EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);

SilverlightApplicationCache above is the namespace of the XAML file.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com

Oct 31, 2011 at 10:51 AM

Thanks, that helped me a lot!!!!

Storing the configuration on the server has the problem that it needs an additional call at the beginning. so, what's in the mean time? My Application needs to access the cache from the start of the application - and if i would load the cache configuration from the server, i would have to wait until this request is done...

Dec 21, 2011 at 7:42 PM
Edited Dec 21, 2011 at 7:44 PM

Hello, please help, I am trying to configure the caching in my Silverlight application but my question is, where you must set, in the web application or in the Silverlight application. Do also check out the example, but necessarily have to generate a file of type: SilverlightApplicationCache.cacheConfig.xaml?

I only need a simple application of configuration in order to understand, then it could deal with more complex

 

Dec 21, 2011 at 7:50 PM
Edited Dec 21, 2011 at 8:22 PM

It's up to you where you want to store your configuration.  You can store it in the web application and read the configuration over the network or you can embed the configuration inside your Silverlight app.

This thread above shows both approaches.

One of the main reasons to host the configuration on the web server is so that changes can be made to the configuration without requiring a redeploy/download of the Silverlight application.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com

Dec 21, 2011 at 8:13 PM

OK my friend, will do everything possible to replicate the example, but if I don't, I'll be bothering you, jejeje

Dec 21, 2011 at 10:08 PM

Hi again, the example "StockTrader V2" in the configuration folder i don't know how to generate the file "StockTraderRI.Silverlight.xaml" to be able to read it from the Silverlight application. Please their kindness helping me with this topic

Dec 22, 2011 at 2:57 AM
Edited Dec 22, 2011 at 3:03 AM

To convert from standard configuration to XAML configuration you can use the configuration tool.  Open the .config file and choose Wizards -> Export to XAML and specify the output file.

For a new project the steps would be something like:

  • Create a New Silverlight Application
  • Use Nuget to add Caching application block
  • In the web app add new web config called Caching.Silverlight.config (or whatever you want)
  • Right Click and say edit Enterprise Library 5 Configuration
  • Select Blocks->Add Caching Settings for Silverlight
  • Add the configuration you want
  • Select Wizards -> Export to XAML name file Caching.Silverlight.Configuration.xaml (or whatever you want)
  • Include Caching.Silverlight.Configuration.xaml file in web project 

You can also hand edit the configuration files.  If you edit within the Silverlight project then intelliesense "just works" so it's not so daunting.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Dec 22, 2011 at 12:54 PM

Really has helped me a lot, thanks for everything

Dec 22, 2011 at 4:01 PM
Edited Dec 22, 2011 at 4:08 PM

Hi Randy, sorry to you bother so much, but I have an error when exporting XAML file (Caching.Silverlight.Configuration.xaml) into the application web in Silverlight, but when I exclude the file XAML from my application web the error disappear. Any suggestions in this regard?

"Cannot resolve dependency to assembly 'System.Windows, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event"

Dec 22, 2011 at 5:55 PM

Here is my solution to my problem. In order to successfully run the configuration Silverlight had to create my 2 configuration files in Silverlight application more not in the web application implementation (gives me error to have the configuration files on the web, I don't know why).

This files are the configuration caching to my application:

  1. Caching.Silverlight.Configuration.config
  2. Caching.Silverlight.Configuration.xaml

Then add these lines of code in the App.xaml file

        public App()
        {
            this.Startup += this.Application_Startup;
            this.UnhandledException += this.Application_UnhandledException;

            InitializeComponent();
            InitializeCachingConfig();
        }

        private static void InitializeCachingConfig()
        {
            var configUri = new Uri("/Configuration/Caching.Silverlight.Configuration.xaml", UriKind.Relative);
            EnterpriseLibraryContainer.ConfigureAsync(configUri);
            EnterpriseLibraryContainer.EnterpriseLibraryConfigurationCompleted += (sender, e) =>
                {
                    if (!e.ConfiguredSuccessfully)
                        throw new InvalidOperationException("Configuration Failed", e.Error);
                };
        }

And finally the code that I use the object cache in LoadCatalogViewModel.cs

 

var cache = EnterpriseLibraryContainer.Current.GetInstance<ObjectCache>("In-Memory Cache");
var cacheItem = cache["CatalogKey"];

if (cacheItem == null)
    cache.Set("CatalogKey", this.Countries, new CacheItemPolicy());

I hope this helps those who have the same problem. 


Now I have another question, there is the possibility of exporting to an XML file and have on hard drive, then read them again and not have to go to the database at the time of having my object in cache. It has Enterprise library this exporter to XML option my object in cache

Any suggestions, thank you

Dec 23, 2011 at 2:54 AM

I'm glad you got it to work.  Although, I'm a bit confused by your posting.

When you call EnterpriseLibraryContainer.ConfigureAsync(configUri); this is invoked from the Silverlight application running in the browser.  ConfigureAsync then makes a call (using WebClient) over the network to the web application running on the web server to load the "/Configuration/Caching.Silverlight.Configuration.xaml".  It sounded to me like you were saying not to put the config file in the web application (which is perfectly valid if you want to embed the configuration within Silverlight).

In terms of the error message you were getting you should look at the file properties and see what the Build Action is.  I've seen the Build Action default to Page which can cause compilation errors.  You can set the Build Action to Content in the web application since the configuration XAML files do not need to be compiled -- they just need to be served to the Silverlight application.

In order to persist data to a local drive you can use the IsolatedStorageCache.  I believe that the StockTrader RI uses both In Memory and Isolated Storage caches.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com