Composing with Static Classes

Nov 11, 2008 at 10:12 PM
First off, I would like to say that so far MEF is very useful for what I am doing, kudos!  Second though, I'd been using the CTP, and I recently upgraded to the new preview 2 version.  With the new version, I noticed that support for composing the imports on static classes seems to have broken (but worked fine on the CTP when I would add a typeof(SomeStaticClass)).  For instance, a static property with a satisfiable import on a static class no longer gets seen as an import.  This is easy to work around, but I was curious about why this change was made (or if it is a bug)?  Thanks!
-Sam
Developer
Nov 13, 2008 at 5:23 AM
For my own information can you give an example of the what actually worked previously and what doesn't work now?

In general static imports are not going to be supported because we cannot reasonably know when to satisfy those imports nor who should actually satisfy those imports. However, we do expect to support static exports.
Nov 13, 2008 at 9:23 PM
Here's an example:

//using MEF CTP
namespace MEFStaticTest
{
    class Program
    {
        static void Main(string[] args)
        {
            CompositionContainer cc = new CompositionContainer();
            cc.AddComponents(new NonStaticTestClass());
            cc.AddComponents(typeof(StaticTestClass));
            cc.Bind();

            Console.WriteLine(StaticTestClass.use == null ? "null" : "not null");
        }
    }

    public static class StaticTestClass
    {
        public static string name { get { return "StaticTestClass"; } }

        [Import(typeof(NonStaticTestClass))]
        public static NonStaticTestClass use
        {
            get;
            set;
        }
    }

    [Export(typeof(NonStaticTestClass))]
    [CompositionOptions(CreationPolicy = CreationPolicy.Factory)]
    public class NonStaticTestClass
    {
        public string name { get { return "NonStaticTestClass"; } }
    }
}

----------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;

//using MEF Preview 2
namespace MEFStaticTest2
{
    class Program
    {
        static void Main(string[] args)
        {
            CompositionContainer cc = new CompositionContainer();
            cc.AddPart(new NonStaticTestClass());
            cc.AddPart(typeof(StaticTestClass));
            cc.Compose();

            Console.WriteLine(StaticTestClass.use == null ? "null" : "not null");
        }
    }

    public static class StaticTestClass
    {
        public static string name { get { return "StaticTestClass"; } }

        [Import(typeof(NonStaticTestClass))]
        public static NonStaticTestClass use
        {
            get;
            set;
        }
    }

    [Export(typeof(NonStaticTestClass))]
    [CompositionOptions(CreationPolicy = CreationPolicy.Factory)]
    public class NonStaticTestClass
    {
        public string name { get { return "NonStaticTestClass"; } }
   
Developer
Nov 13, 2008 at 9:55 PM
When we release the final version of MEF this scenario will likely not work at all.

It looks to me like you are trying to create a singleton and you want everyone that uses this to be forced to take a static dependency on StaticTestClass. Why not have them explicitly import NonStaticTestClass directly? And if you wanted there to be only one instance of NonStaticTestClass just make the CreationPolicy.Singleton (which is the default).
Nov 13, 2008 at 11:04 PM
That was a simple example to show the change in behavior I'd talked about, the real use of it is a bit more complicated.  In the real thing I'm importing multiple contract-satisfying types into a factory class, that then uses those imports to help satisfy some of its factory obligations.  So the simple workaround is to make that static factory class into a singleton with all static methods and add the singleton instance to the composition (instead of the static type), but I was wondering if this is the correct way, or will there be static class composition eventually again?  Thanks!