Mef2P4 MVC3 How to resolve

Dec 15, 2011 at 12:35 PM

I have created an attribute derived from HandleErrorAttribute. My attribute is instantiated and registered with the GlobalFilters in the Global.asax.

How can I access the composistion container inside my attribute? I want to get my logger which I have registered with MEF. I know it is registered ok, because it works fine in my controllers by constructor injecttion. (ILogger is exported as an open generic).

I tried this:

var logger = DependencyResolver.Current.GetService<ILogger<HandleErrorAndLogAttribute>>();

But it returns null.

How should I compose types by hand?

Regards, Jaap

Dec 19, 2011 at 9:15 AM

I did some further research on this. This are my findings so far:

The CompositionScopeDependencyResolver uses GetExportedValueOrDefault<object>(AttributedModelServices.GetContractName(serviceType)), but it appears that this does not work when serviceType is a generic (whether serviceType is an interface or class).

Suppose I have this test class:

    [Export]
    class MyTestClass<T>
    {
        public T Value { getset; }
    }

then

container.GetExportedValue<MyTestClass<int>>()

works, but 

container.GetExportedValue<object>(AttributedModelServices.GetContractName(typeof(MyTestClass<int>)))

does not work. The last method is the way the DepencyResolver works which is used in Mvc.

The same applies when you want to get a service by interface:

    interface IAnotherTest<T>
    {
 
    }
 
    [Export(typeof(IAnotherTest<>))]
    class MyGeneric<T> : IAnotherTest<T>
    {
 
    }

then

container.GetExportedValue<IAnotherTest<int>>()

works, but this does not work:

container.GetExportedValue<object>(AttributedModelServices.GetContractName(typeof(IAnotherTest<int>)))

In both cases it works when you change <object> to the requested type.

 

Dec 19, 2011 at 3:27 PM

Thanks for the additional information, this is good to know.

From: JaapM [email removed]
Sent: Monday, December 19, 2011 2:16 AM
To: Nicholas Blumhardt
Subject: Re: Mef2P4 MVC3 How to resolve [MEF:283077]

From: JaapM

I did some further research on this. This are my findings so far:

The CompositionScopeDependencyResolver uses GetExportedValueOrDefault<object>(AttributedModelServices.GetContractName(serviceType)), but it appears that this does not work when serviceType is a generic (whether serviceType is an interface or class).

Suppose I have this test class:

    [Export]
    class MyTestClass<T>
    {
        public T Value { get; set; }
    }

then

container.GetExportedValue<MyTestClass<int>>()

works, but

container.GetExportedValue<object>(AttributedModelServices.GetContractName(typeof(MyTestClass<int>)))

does not work. The last method is the way the DepencyResolver works which is used in Mvc.

The same applies when you want to get a service by interface:

    interface IAnotherTest<T>
    {
 
    }
 
    [Export(typeof(IAnotherTest<>))]
    class MyGeneric<T> : IAnotherTest<T>
    {
 
    }

then

container.GetExportedValue<IAnotherTest<int>>()

works, but this does not work:

container.GetExportedValue<object>(AttributedModelServices.GetContractName(typeof(IAnotherTest<int>)))

In both cases it works when you change <object> to the requested type.

Dec 20, 2011 at 3:52 PM

Now recorded in tracker: http://mef.codeplex.com/workitem/14571

Dec 20, 2011 at 6:55 PM
Edited Dec 20, 2011 at 6:59 PM

Thanks

Dec 20, 2011 at 6:59 PM
Edited Dec 20, 2011 at 7:00 PM

Hopefully it will be fixed in the next preview (or some earlier build).

Because the workaround you describe does not work when you have no idea about the closed generic type at design-time.

In my case I have a generic Controller. In a ControllerFactory I determine the closed generic Controller type, which should be instantiated.

Creating a non-generic wrapper would require a wrapper class (or inherited class) for every possible closed generic Controller type.

Would be a lot of classes in my case.

Feb 20, 2012 at 2:17 PM

Any idea if this will be fixed in MEF 2?

Or will it be suspended to MEF 3?

Feb 20, 2012 at 3:26 PM

This is part of the composition provider NuGet package, so we're likely to address this before MEF 3. Sorry about the wait - we're working on a status update for MEF and should get it onto the BCL Team blog in the next few weeks.

Cheers!

Nick