Catalog Caching - Any examples?

Dec 3, 2008 at 10:36 AM
Hi, from what I can see it appears that the API intended for applications to use to cache catalogs is provided via the ComposablePartCatalogCachingServices class.

Are there any examples of usage of this class for caching?

Particularly are there any examples of use of caching together with an AggregatingComposablePartCatalog.

I'd like to use the aggregate catalog together with multiple instances of directory catalogs so that I can store addins within multiple directories nested under an 'AddIn' directory.

However, I'm interested in supporting caching of the aggregate catalog, and it's unclear to me how the caching should be used.  Looking at the various classes, it looks like the aggregate catalog will support caching of children providing they themselves support caching via implementation of the ICachedComposablePartCatalog interface.  And since all catalog classes including the directory category implement this interface it would appear the use case should be supportable.

Any help is greatly appreciated.

Thanks,
Phil

Dec 3, 2008 at 2:28 PM
I believe the key to caching is the Export<T> object. Think of it as a lazy-initialization wrapper around your part. When the GetExportedObject for the first time it initializes the object and caches it for further use. This is how Glenn describes it in his blog post abour Preview 3

Catalog Cache - The catalog now builds a persistent cache of all the metadata for parts in the catalog. Until the part is instantiated, it's assembly will not get loaded. For lazy loading this means if a part imports an Export<IFoo>  then the Foo  assembly will not be loaded until GetExportedObject is called.

Quoted from http://blogs.msdn.com/gblock/archive/2008/11/26/mef-re-factored-preview-3-has-shipped.aspx

Basically you do

[Import(...)]
public Export<YourType> Part { get; set; }


and you can wrap it all up for a collection property as well

[Import(...)]
public IEnumerable<Export<YourType>> Parts { get; set; }

The way to then consume it is

YourType t = Part.GetExportedObject();
Dec 3, 2008 at 3:53 PM
CodeJunkie ... looks like I might have completely misread the intention of the cache:  I didn't read the comment thoroughly enough...

My assumption was that caching provided a performance improvement by avoiding the hit of reflection over assemblies in order to build up a catalog - similar to the functionality provided by System.AddIn.  So, you'd only have to regenerate a cache when you knew the list of installed addins had changed thus minimizing application startup delay.

I'm still wondering however, if caching provides both lazy loading *and* the performance improvement of avoiding reflection.

Regards,
Phil

Dec 3, 2008 at 6:09 PM

It does provide the perf improvement of avoiding continual reflection as well as the benefit of not loading assemblies until they are needed.

From: pspidey [mailto:notifications@codeplex.com]
Sent: Wednesday, December 03, 2008 7:54 AM
To: Glenn Block
Subject: Re: Catalog Caching - Any examples? [MEF:41362]

From: pspidey

CodeJunkie ... looks like I might have completely misread the intention of the cache: I didn't read the comment thoroughly enough...

My assumption was that caching provided a performance improvement by avoiding the hit of reflection over assemblies in order to build up a catalog - similar to the functionality provided by System.AddIn. So, you'd only have to regenerate a cache when you knew the list of installed addins had changed thus minimizing application startup delay.

I'm still wondering however, if caching provides both lazy loading *and* the performance improvement of avoiding reflection.

Regards,

Phil

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Dec 3, 2008 at 6:53 PM
That's excellent news, thanks Glenn.

Are there any examples planned, or maybe even just a small code snippet that would show the intended usage pattern?

Am I correct in my interpretation that ComposablePartCatalogCachingServices is the class intended to expose the user facing API, and that this is the class I should be using?
How should it be used?

Any help greatly appreciated.

Thanks,
Phil

Dec 3, 2008 at 7:02 PM

What are you trying to do? You shouldn’t be accessing that service directly, it’s an implementation detail.

Glenn

From: pspidey [mailto:notifications@codeplex.com]
Sent: Wednesday, December 03, 2008 10:53 AM
To: Glenn Block
Subject: Re: Catalog Caching - Any examples? [MEF:41362]

From: pspidey

That's excellent news, thanks Glenn.

Are there any examples planned, or maybe even just a small code snippet that would show the intended usage pattern?

Am I correct in my interpretation that ComposablePartCatalogCachingServices is the class intended to expose the user facing API, and that this is the class I should be using?

How should it be used?

Any help greatly appreciated.

Thanks,

Phil

Read the full discussion online.

To add a post to this discussion, reply to this email (MEF@discussions.codeplex.com)

To start a new discussion for this project, email MEF@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Dec 3, 2008 at 7:50 PM
Glenn, I'm trying to create a catalog which supports installation of addins in nested subdirectories of an AddIn folder, such that each addin has it's own subdirectory under a common AddIn directory.

The way I was looking at doing this was to use the aggregate catalog together with a number of child directory part catalogs.  I would create one directory part catalog per subdirectory and add them to the aggregate catalog.

However, I would also like to use the support for caching to avoid having to reflect over everything at startup.

Now it's not at all clear to me what an application needs to do to support caching, particularly in this use case.  I mentioned the ComposablePartCatalogCachingServices only because from looking at the source code, it looked like that might be the class I should be using.  From what you write, it sounds like my guess is wrong.  It's just difficult to tell without more info what I need to do.

Regards,
Phil
Coordinator
Dec 3, 2008 at 8:40 PM
Edited Dec 3, 2008 at 8:40 PM
Here is some sample code for how to load and save a directory watching catalog.

        private static DirectoryPartCatalog LoadCatalog()
        {
            if (File.Exists(catalogCacheFileName))
            {
                return (DirectoryPartCatalog)ComposablePartCatalogCachingServices.ReadCatalogFromCache(catalogCacheFileName);
            }
            else
            {
                return new DirectoryPartCatalog(extensionsDirectory, true);
            }
        }

        private static void SaveCatalog(DirectoryPartCatalog catalog)
        {
            if (!catalog.IsCacheUpToDate)
            {
                ComposablePartCatalogCachingServices.CacheCatalog(catalog, catalogCacheFileName);
            }
        }

Writing your own catalog which supports caching via the ICachedComposablePartCatalog interface would be significantly more difficult, I think.

Daniel
Dec 3, 2008 at 9:04 PM
Excellent!  Thanks a lot Daniel.  Exactly what I was looking for.  I was guessing it would be something like that but wasn't sure.

Much appreciated,
Phil

Dec 5, 2008 at 3:56 PM
I added the example caching code to my project, and it seems to save and load correctly. But after loading from the cache, SaveCatalog will generate an IOExcpetion because the cache file is still in use.  Is there something I need to be Disposing?
Dec 8, 2008 at 10:56 PM
That would be a problem with our current caching implementation as the cache is locked. We will have a better story in the future, but for now I suggest that you clone the cache on startup and then load it, while saving the cache to its original location
Oleg