Sofa, AvalonDock and MEF
Sofa and MEF !
What is AvalonDock ?
AvalonDock is a WPF controls library which can be used to create a docking layout system like that is present in Visual Studio.
It supports fly-out panes, floating windows, multiple docking manager in same window, styles and themes and it can host WinForms controls.
See more at the AvalonDock web site,
What is Sofa?
Sofa wraps AvalonDock and provides:
- Easier programming
- Enhanced features
- Additional features
See more at the Sofa web site,
What problems does MEF solve?
MEF presents a simple solution for the runtime extensibility problem.
MEF provides a standard way for the host application to expose itself and consume external extensions.
MEF offers a set of discovery approaches for your application to locate and load available extensions.
MEF allows tagging extensions with additonal metadata which facilitates rich querying and filtering.
See more at the MEF web site.
There is a symmetry between the docking layout of Sofa/Avalon and the MEF component architecture : MEF will allow integration of external components that will easily be represented as tabbed or splited windows.
The MEF XFileExplorer example
The example below is based on the MEF FileExplorer which can be found in the MEF preview download (MEF\MEF2_Preview2\Samples\CS\XFileExplorer) and has been "translated" into a set of Sofa components.
It is a basic file explorer with its treeview, its contents pane and 3 additional functionalities, a size pane showing a graphical representation of file sizes, a preview pane and favorites.
It is made of a main component named Shell and one "sub-component" for each functionality.
Once the application is translated into Sofa components and runs in the Sofa container its appearance is not that different.
You can find it as a Component of the SofaExplorer 1.1 example on the download page of the Sofa web site.
But the user can now customize it:
Another additional feature is the XFileExplorer is now a set of Sofa components and it becomes easy to manage many instances of each set using Sofa perspectives (top left menu). A default filepath is associated to each perspective and allows managing filepathes favorites.
The main goal of this documentation is however not to demonstrate hosting an application as a Sofa component can easily provide additional functionalities: It is to show how MEF concepts and Sofa/AvalonDock concepts fits to each other and are easy to implement.
Micro MEF tutorial
The way MEF works is very simple: MEF components, called Composable Parts, declare they are composable parts:
[Export("Microsoft.Samples.XFileExplorer.FileExplorerViewContract", typeof(UserControl))] public partial class PreviewView : UserControl { ...Then the host application registers composable parts using the CompositionContainer.ComposePart() method: In this example all Composable Parts that are in the executing assembly will be registered:
private void Compose() { var catalog = new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()); var container = new CompositionContainer(catalog); container.ComposeParts(this); }The XFileExplorer example uses a different object, the CompositionBatch, but basically it is the same work.
At last the hosting application can retrieve composable parts: For instance in the XFileExplorer the 2 following lines will make the _views object automatically loaded by MEF at run time.
[ImportMany("Microsoft.Samples.XFileExplorer.FileExplorerViewContract", AllowRecomposition=true)] private Lazy<UserControl, IFileExplorerViewMetadata>[] _views = null;
Sofa and MEF
When the MEF hosting application becomes a Sofa component it is no longer an application but a UserControl. And it looses its App.xaml.cs file where the Compose method is usually stored. This piece of code has to be moved to the main component. It is Shell.xaml.cs in our example.
Sofa has a central repository where all component running in the container are stored. This allows retrieving components registered in the Sofa container instead of components of the executing assembly:
private bool Compose() { var catalog = new AggregateCatalog(); //Use Sofa component list foreach (CmpModel cmp in Container.SofaContainer.CmpModelList) { catalog.Catalogs.Add(new AssemblyCatalog(cmp.ControlDllName)); ...Then Sofa components (ie MEF composable parts) must be loaded in AvalonDock.
The usual way of loading a Sofa component is to use the SofaContainer.OpenComponent method. This creates a new instance of the component and loads it into an AvalonDock window. The return value is an object storing information about the component.
cmpLoaded = Container.SofaContainer.OpenComponent("ComponentName")
When using MEF instances of components are already created. The AddComponent method replaces the OpenComponent method: It uses an already instanciated object.
A cmpModel object is created to store parameters defining the graphical behaviour of the component.
cmpLoaded = Container.SofaContainer.AddComponent(ComponentInstance, cmpModel);
For instance in Shell.xaml.cs:
private void ReloadAllViews() { … //_views stores MEF objects foreach (var view in _views.OrderBy(i => i.Metadata.DockId)) { //Get the instance of current view var childPane = view.Value; … //Prepare a CmModel object as parameter for the AddComponent method CmpModel cmpModel = new CmpModel(); … switch (view.Metadata.Docking) { case Dock.Top: … cmpModel.AvalonPaneGroup = "TopSide"; cmpLoaded = Container.SofaContainer.AddComponent(childPane, cmpModel);And that's it. All the rest of the code of the original example is not impacted when running as a Sofa component. Some lines of code were added to handle Sofa multi-instance and the default filepath associated to each instance but everything needed to convert a MEF application into a Sofa component using MEF is here.
Sofa not only allows creating MEF enabled applications. It adds an interesting feature to MEF applications: Components are deployed separately.
In the original sample all MEF composable parts must be built in the same directory so that the MEF Compose() method can find them. If a new component is added or modified all the application needs to be re-packaged and re-deployed. And all components of the package are deployed without the user can choose which one he wants.
On the contrary, when using Sofa, MEF components are deployed as Sofa components, separately from each other’s. This gives flexibility in application development and deployment. This may also allow users selecting in a toolset the tool or the version of the tool they want to use.
Post Comment
Looking forward to reading more. Great post.Really thank you! Want more.
Your style is really unique compared to other people I ave read stuff from. Thanks for posting when you ave got the opportunity, Guess I will just book mark this site.
Not loads of information and facts in this particular tale, what happened into the boat?
I similar to Your Post about Khmer Funny
Many thanks for sharing this great post. Very inspiring! (as always, btw)
Wow, great post.Much thanks again. Great.
Pretty seаАааАТtion ?f аАааАТ?ntent.
Outstanding quest there. What happened after? Take care!
your e-mail subscription link or e-newsletter service.
Major thankies for the article.Really thank you! Really Great.
You have brought up a very wonderful points , thanks for the post.
There may be noticeably a bundle to learn about this. I assume you made certain nice points in features also.
It as best to take part in a contest for among the best blogs on the web. I will advocate this website!
Keep up the superb work , I read few posts on this web site and I conceive that your web blog is rattling interesting and contains bands of great information.
Valued Personal Traits Hello, you used to write great, but the last several posts have been kinda boring I miss your great writings. Past few posts are just a bit out of track! come on!
Very Fascinating Blog! Thank You For This Weblog!
You don at have to remind Air Max fans, the good people of New Orleans.
Im thankful for the blog post.Much thanks again. Awesome.
Really enjoyed this article post.Really thank you! Fantastic.
Thank you for the auspicious writeup. It in fact was a amusement account it. Look advanced to more added agreeable from you! By the way, how could we communicate?
Regards for helping out, excellent info.
Singapore New Property How do I place a social bookmark to this webpage and I can read updates? This excerpt is very great!
In my opinion you are not right. I am assured. Write to me in PM, we will discuss.
I truly appreciate this article.Really thank you! Fantastic.
I reckon something truly special in this web site.
Really informative article.Thanks Again. Keep writing.
Very clean web site , appreciate it for this post.
yours and my users would really benefit from some of
Very interesting details you have observed, thank you for putting up.
This article has truly peaked my interest. I am going to take a note of your blog and keep checking for new
iu9cK8 Wow, incredible blog structure! How long have you been running a blog for? you make running a blog glance easy. The total look of your web site is magnificent, let alone the content material!
Very informative blog article.Thanks Again. Keep writing.
Really informative article post.Thanks Again. Much obliged.
Inspiring story there. What happened after? Take care!
Really informative blog post. Really Cool.
who these programs may be offered to not fake this will be the reason why such loans
This site truly has all the info I needed about this subject and didn at know who to ask.
Wow! I cant think I have found your blog. Extremely helpful info.
I savor, result in I found exactly what I used to be having a look for. You have ended my four day long hunt! God Bless you man. Have a great day. Bye
pretty beneficial stuff, overall I feel this is really worth a bookmark, thanks
Would you be interested in trading links or maybe guest
I truly appreciate this post. I have been looking everywhere for this! Thank God I found it on Google. You ave made my day! Thanks again
Really appreciate you sharing this blog article.Really thank you! Cool.
I really liked your blog article.Thanks Again. Really Great.
Red your site publish and beloved it. Have you at any time thought about visitor putting up on other associated weblogs comparable to your weblog?
This is really interesting, You are a very skilled blogger. I have joined your feed and look forward to seeking more of your fantastic post. Also, I ave shared your website in my social networks!
Thanks-a-mundo for the article post.Really looking forward to read more. Keep writing.
Thank you ever so for you article.Much thanks again. Awesome.
It as not that I want to replicate your web-site, but I really like the style. Could you tell me which style are you using? Or was it tailor made?
know who you might be but definitely you are going to a well-known blogger when you are not already.