How do I clear the WPF / XAML type cache in a plugin project

1.9k views Asked by At

I'm writing a plugin for an application (Autodesk Revit Architecture 2011, if you need to know).

During debugging, I'd like to recompile my plugin and reload that in the host. My specific host even provides an Add-In Manager that simplifies this process, using Assembly.Load. For Windows.Forms plugins, this works like a charm.

When I use WPF, this breaks down. At first, I was getting an error along these lines (I added some formatting to make it easier for you to read:

System.Windows.Markup.XamlParseException:  
[A]MyApp.Controls.MyControl cannot be cast to [B]MyApp.Controls.MyControl. 
Type A originates from 'MyApp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location '%PATHA%'. 
Type B originates from 'MyApp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null' in the context 'LoadNeither' at location '%PATHB'.  
Error at object 'MyApp.Controls.MyControl' in markup file 'MyApp;component/controls/mydialog.xaml'.

I have also taken the liberty of renaming controls, namespaces and paths to protect the innocent and me, the culprit.

I assume this is because the XAML parser keeps a cache of types it has already loaded.

My first step was to change the assembly versions, by setting AssemblyInfo.cs/[assembly: AssemblyVersion("2.0.*"). This just moves the error a step further:

System.Windows.Markup.XamlParseException:  
Unable to cast object of type 'MyApp.Controls.MyControl' to type 'MyApp.Controls.MyControl'.  
Error at object 'MyApp.Controls.MyControl' in markup file 'MyApp;component/controls/mydialog.xaml'. 
---> System.InvalidCastException: Unable to cast object of type 'MyApp.Controls.MyControl' to type 'MyApp.Controls.MyControl'.
2

There are 2 answers

1
Andrii On

Don't know how to clean the cache, but as workaround I'd try to load XAML directly with XamlReader.Load and see if it works. Check http://msdn.microsoft.com/en-us/library/ms590388.aspx#Y309

2
Kent Boogaart On

It sounds to me like you'd be best off performing compilation in a separate AppDomain. You can then throw that AppDomain away once the compilation is done.

The exact interface between your main AppDomain and compilation AppDomains is not really something I can comment on since you've not provided details in your question.