MEFContrib online

Sep 30, 2008 at 4:52 AM
The Managed Extensibility Framework project now has a community contribution site at http://www.CodePlex.com/MEFContrib

If you have code that would benefit the community or want to help with existing project(s) you are encouraged to join.  The current project MEFPOC is a proof of concept that integrates MEF with the CompositeWPF.  Features such as the region manager, event aggregator and commands will be available (region manager and event aggregator currently functional).

Could use a code review on the current source upload - blogged about HERE.   This is a Proof of Concept; once fully integrated TDD/refactoring will commence as applicable.

Sep 30, 2008 at 5:15 AM
Nice job Bill!

-----Original Message-----
From: "BillKrat" 
To: "Glenn Block" 
Sent: 9/29/2008 8:52 PM
Subject: MEFContrib online  [MEF:36713]

From: BillKrat

The Managed Extensibility Framework project now has a community contribution site at http://www.CodePlex.com/MEFContrib

If you have code that would benefit the community or want to help with existing project(s) you are encouraged to join. The current project MEFPOC is a proof of concept that integrates MEF with the CompositeWPF. Features such as the region manager, event aggregator and commands will be available (region manager and event aggregator currently functional).

Could use a code review on the current source upload - blogged about HERE. This is a Proof of Concept; once fully integrated TDD/refactoring will commence as applicable.

Sep 30, 2008 at 6:30 AM

Bill, I'd love to see in a follow up post more on how MEF plays into your design, i.e. what things do you use MEF for vs Unity. Do you store references in both places, or scope them.

Glenn

Sep 30, 2008 at 6:37 PM
These are questions I should start sorting out this evening - my first approach was rather shotgun (just make it work) and now I have to take a more granular approach to integration.   I'll be sure to post follow-ups as I move along; always looking forward to community feedback for better ways.

I'm going to introduce Ryan to the work Michael Puleio and Chris Taveres did HERE, teach him what I know about the CompositeWPF and see if I can't motivate him (doesn't take much) to come up with a MEF ASP.NET contribution.
Oct 2, 2008 at 4:00 AM
Would appreciate some feedback on the direction I'm taking to integrate MEF / CompositeWPF.  Currently the MEFContrib POC can successfully launch MEF parts and CompositeWPF modules as separate entities.   I added an IUnityContainer reference to the "DebugLogger" Part and am looking to have it Built by the unity container.

The current sequence of events in the MEFBootStrapper : UnityBootstrapper follows:

In Constructor:
1. MEF is composed  (imports / exports resolved)
2. UnityBootstrapper.Run() is executed
3. IEnumerable of ComposableExport objects are iterated through and displayed to Debug output

Next I will attempt to BuildUp the exported object references in the MEFBootStrapper in step 3 (initial attempts failed; have to debug Unity builder to find why)

Risk: I may not have access to hooks in CompositionContainer upon release



Changes made to CompositionContainer follow:

/// <summary>
/// MEFCONTRIB: - where to put this...
/// </summary>
/// <typeparam name="T"></typeparam>
public class DataEventArgs<T> : EventArgs
{
    public T Data {get; private set; }
    public DataEventArgs(T data )
    {
        Data = data;
    }
}

public partial class CompositionContainer : ICompositionService, IDisposable
{
    /// <summary>
    /// MEFCONTRIB: - Event raised when exports resolved
    /// </summary>
    public static event EventHandler<DataEventArgs<IEnumerable>> OnResolved;

...
...
...

private CompositionResult SatisfyImports(ComposablePartState partState, ComposablePart part, Func<ComposableImport, bool> filter)
{
    CompositionResult result = CompositionResult.SucceededResult;

    foreach (ComposableImport import in part.ComposableImports.Where(filter))
    {
        partState.RequiresFullyComposed = import.RequiresFullyComposedExports;

        CompositionResult<IEnumerable<ComposableExport>> valueResult = this.TryResolve(import);
        result = result.MergeResult(valueResult.ToResultWithNoValue());

        if (!valueResult.Succeeded)
        {
            continue;
        }

        result = result.MergeResult(part.TrySetImport(import, valueResult.Value.Cast<ComposableItem>()));

        // MEFCONTRIB: - if there are any results then raise event
        if (OnResolved != null && valueResult.Value.Any())
            OnResolved(result, new DataEventArgs<IEnumerable>(valueResult.Value));

 



MEFCompositionContainer.cs follows:

namespace MEFContrib.Library.Base
{
    public class MEFCompositionContainer : CompositionContainer
    {
        List<ComposableExport> exports = new List<ComposableExport>();

        /// <summary>
        /// Constructor - subscribe to OnResolved event so exports can
        /// be processed
        /// </summary>
        /// <param name="resolver"></param>
        public MEFCompositionContainer(ValueResolver resolver)
            : base(resolver)
        {
            OnResolved+=new EventHandler<DataEventArgs<IEnumerable>>(MEFCompositionContainer_OnResolved);
        }

        /// <summary>
        /// Handler for events raised by SatisfyImports when export is resolved
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void MEFCompositionContainer_OnResolved(object sender, DataEventArgs<IEnumerable> e)
        {
            // At this point we don't have a unity container yet
            // add to exports list so we can build when we do
            foreach (ComposableExport export in e.Data)
                exports.Add(export);
        }

        /// <summary>
        /// Get list of exports that need to be built by Unity
        /// </summary>
        /// <returns></returns>
        public List<ComposableExport> GetExportsToBuild()
        {
            return exports;
        }
       
    }
}




I have the following note in ExportServices.cs --- if Unity was run() prior to MEF being composed then a thought was "could Unity be used to create the export instance?"....

        internal static Export CreateExport(Type exportType, ComposableExport export)
        {
            Assumes.NotNull(exportType, export);
            // MEFCONTRIB: - possible access point?
            Export ExportObj = (Export)Activator.CreateInstance(exportType, export);
            return ExportObj;
        }



Oct 3, 2008 at 1:35 AM
Edited Oct 3, 2008 at 1:38 AM

Proof of concept complete (ComponentModel restored to orginal source).  "Forest through the trees"; getting Unity into a MEF part was as simple as the following:

[Export(typeof(ILogger))]

[ExportMetadata("type","MessageBoxLogger")]

public class MessageBoxLogger : ILogger

{

    private IUnityContainer _unityContainer;

    [Import(typeof(IUnityContainer))]

    public IUnityContainer UnityContainer

    {

        get { return _unityContainer; }

        set { _unityContainer = value; }

    }

 

    public MessageBoxLogger()

    {

    }

 

    public void Log(string message, Category category, Priority priority)

    {

        MessageBox.Show(UnityContainer.Resolve<IMockClass>().Message, message);

    }

Now we can have the best of MEF, the CompositeWPF and Unity.

Oct 3, 2008 at 7:07 AM
That works for me! I totally like getting the magic injection of the unityContainer so that you may do stuff inside your code too. Magic injection is great but not always good enough.

M.

On Fri, Oct 3, 2008 at 02:35, BillKrat <notifications@codeplex.com> wrote:

From: BillKrat

Proof of concept complete (ComponentModel restored to orginal source). "Forest through the trees"; getting Unity into a MEF part was as simple as the following:

    [Export(typeof(ILogger))]
    [ExportMetadata("type","MessageBoxLogger")]
    public class MessageBoxLogger : ILogger
    {
        private IUnityContainer _unityContainer;
        [Import(typeof(IUnityContainer))]
        public IUnityContainer UnityContainer
        {
            get { return _unityContainer; }
            set { _unityContainer = value; }
        }
 
        public MessageBoxLogger()
        {
        }
 
        public void Log(string message, Category category, Priority priority)
        {
            MessageBox.Show(UnityContainer.Resolve<IMockClass>().Message, message);
        }

Now we can have the best of MEF, the CompositeWPF and Unity.

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




--
Magnus Mårtensson
Senior Consultant - Scrum Master - MCSD, MCTS
Dotway AB

Tel: +46 (768) 51 00 36

http://blog.noop.se/