Showing posts with label MEF. Show all posts
Showing posts with label MEF. Show all posts

Tuesday, 23 February 2016

Debug MEF



Nice article about debugging MEF

http://ihadthisideaonce.com/2012/01/31/stop-guessing-about-mef-composition-and-start-testing/

And would it be nice if you can run composition testing?
here is sample example how to do this:
http://ihadthisideaonce.com/2012/06/12/mef-composition-tests-redux/

Saturday, 2 February 2013

Copy MEF Plugins to directory

MEF and Plugins directory

I have created a project in which I wanted to use plugins directory.
Now every plugin has multiple dlls that are required,

Step one I want to copy every dll into plugins directory using post build command.


xcopy "$(TargetDir)*.dll" "$(SolutionDir)ConsoleApplication2\bin\debug\plugins\" /Y /I

Common switches used for

/I - treat as a directory if copying multiple files
/Q - Do not display the files being copied.
/S - Copy subdirectories unless empty.
/E - Copy empty subdirectories.
/Y - Do not prompt for overwrite of existing files.
/R - Overwrite read only files.
 
more information you can find when you type: help xcopy into your command line

Tuesday, 3 July 2012

Sample of MEF composition factory

I have been introduced to MEF quite while ago, but For sample applications I always like to have small working code to use in order to make sure everything is working before I start on something more complex.

Here I have prepared small example of MEF composition with only one source.
The source is executing location in project.
Note: If you are using MEF in website, the code is on the same place where is your main web.config, unless you specified different location.

Eample:

This class will satisfy all dependencies for class "MyClass" using static composition factory.

  public static class Compose
    {
        /// <summary>
        /// Composes the factory.
        /// </summary>
        public static void ComposeFactory(object myObject)
        {
            var catalog = new AggregateCatalog(
                new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly()),
                new DirectoryCatalog(@"."));

            foreach (var container in catalog.Parts.Select(part => new CompositionContainer(catalog)))
            {
                container.ComposeParts(myObject);
            }        }
    }


Where usage might be such as:

public class MyClass(){

public MyClass(){
   Compose.ComposeFactory(this);
}

[Import(typeof(ILogger))]
 public ILogger Logger{get;set;}

// some of your implementation
}


Point of interest.

MEF has two major import types: Import and ImportMany

[Import] or [Import(typeof(IMyInterface))]

Import is used where you want to import only one item.
Unless you specify the typeof MEF will inspect the object of its decoration and automatically try to satisfy the dependency from catalog.
My preference is the second option, which allows you to be specific which object is supposed to satisfy this injection.

Import can be null.


[ImportMany] or [ImportMany(typeof(IMyInterface))]

Import many has to have at least one item, otherwise you will receive an exception.
Again you can leave the satisfaction of the dependency on MEF or be specific.

Monday, 30 April 2012

Implementing MEF with list of attributes

After working with Managed Extensibility Framework or MEF (http://mef.codeplex.com/) for a while, I came across a case when I needed to add attributes to different classes in order to distinguish implementation from classes.

As sample scenario you have different implementation of service and you want to set specific Ids of services to run in different way.

To do this using MEF is a bit different as we need to find out which implementation the one we want to use.

As solution I have chosen to use decoration something like this:
    [SignalSystemData(name, array)]
Where variables are:
  1.  name: variable name so we can identify the string between our classes and implementations.
  2.  array: related items for this implementation
And we come up with something like:

    [SignalSystemData("ServiceIds", new int[]{2,5,3 , 15,16,300,301,302,305})]




After searching modification of code the solution is here:




namespace ConsoleApplication1
{
   using System;
   using System.Collections.Generic;
   using System.ComponentModel.Composition;
   using System.ComponentModel.Composition.Hosting;
   using System.Linq;
   using System.Reflection;

    internal class Program
    {
        private static void Main(string[] args)
        {
            int serviceIdToCall = 305;

            var c = new Class1();
            var v = c.EditorSystemList;
           
            foreach (var lazy in v.Where(x=>x.Metadata.LongName=="ServiceIds"))
            {
                if (lazy.Metadata.ServiceId.Contains(serviceIdToCall))
                {
                    var v2 = lazy.Value;
                    // v2 is the instance of MyEditorSystem
                    Console.WriteLine(serviceIdToCall.ToString() + " found");

                }else
                {
                    Console.WriteLine(serviceIdToCall.ToString() + " not found");
                }
            }

            Console.ReadKey();
        }
    }

    public class Class1
    {
        [ImportMany]
        public IEnumerable<Lazy<IEditorSystem, IEditorSystemMetadata>> EditorSystemList;

        public Class1()
        {
            var catalog = new AggregateCatalog(
                new AssemblyCatalog(Assembly.GetExecutingAssembly()));
            var container = new CompositionContainer(catalog);
            container.ComposeParts(this);
            Console.Write("Composition completed");
        }
    }

    [Export(typeof (IEditorSystem))]
    [SignalSystemData("ServiceIds", new int[]{2,5,3 , 15,16,300,301,302,305})]
    public class MyEditorSystem2 : IEditorSystem
    {
        public void Test ()
        {
            Console.WriteLine("ServiceID : 2");
        }
    }

    [Export(typeof(IEditorSystem))]
    [SignalSystemData("ServiceIds", new [] {1, 20})]
    public class MyEditorSystem1 : IEditorSystem
    {
       
        #region Implementation of IEditorSystem

        public void Test()
        {
            Console.WriteLine("ServiceID : 1");
        }

        #endregion
    }


    public interface IEditorSystem
    {
        void Test();
    }

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class SignalSystemDataAttribute : ExportAttribute
    {
        public SignalSystemDataAttribute(string longName, params int[] serviceId)
            : base(typeof (IEditorSystem))
        {
            LongName = longName;
            ServiceId = serviceId;
        }

        public string LongName { get; set; }
        public int[] ServiceId { get; set; }

    }

    public interface IEditorSystemMetadata
    {
        string LongName { get; }
        int[] ServiceId { get; }
    }   
}