Constructor injection & dynamic assembly NotSupportedException

Sep 5, 2011 at 11:01 AM

Hi,

I got a strange behavior with the following code (unit test). In Debug, it succeeds, but in Release, it fails with a NotSupportedException thrown with message : "invoked member is not supported in a dynamic assembly" (member refers to Assembly.GetCallingAssembly().CodeBase). I do not understand how Debug and Release can have different behavior ?

 

[TestClass]
    public class UnityTests
    {
        [TestMethod]
        public void DynamicAssemblyError()
        {
            IUnityContainer unity = new UnityContainer();
            unity.RegisterType<IClassToInject, ClassToInject>(new ContainerControlledLifetimeManager());
            unity.RegisterType<IClassToResolve, ClassToResolve>(new ContainerControlledLifetimeManager());

            IClassToResolve resolvedObject = unity.Resolve<IClassToResolve>();
        }
    }

    public interface IClassToResolve { }

    public class ClassToResolve : IClassToResolve
    {
        public ClassToResolve(IClassToInject classToInject)
        {
            classToInject.GetSomethingRelatedToCallingAssembly();
        }
    }

    public interface IClassToInject
    {
        string GetSomethingRelatedToCallingAssembly();
    }

    public class ClassToInject : IClassToInject
    {
        public string GetSomethingRelatedToCallingAssembly()
        {
            return Assembly.GetCallingAssembly().CodeBase;
        }
    }

Note that Unity seems to "optimize" something, calling classToinject.GetSomethingRelatedToCallingAssembly() outside ClassToResolve constructor, it seems really weird, here the stack in Release when exception is thrown :

System.Reflection.Emit.InternalAssemblyBuilder.get_CodeBase()UnityTests.ClassToInject.GetSomethingRelatedToCallingAssembly() in C:\Dev\UnityTests\UnityTests.cs: line 74
BuildUp_UnityTests.ClassToResolve(IBuilderContext )Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\DynamicMethodBuildPlan.cs: line 37
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs: line 43
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs: line 110
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs: line 511
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs: line 515
Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs: line 173
Microsoft.Practices.Unity.UnityContainerExtensions.Resolve[T](IUnityContainer container, ResolverOverride[] overrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainerExtensions.cs: line 504
UnityTests.UnityTests.DynamicAssemblyError() in C:\Dev\UnityTests\UnityTests.cs: line 45

Moreover, note that if I store classToinject.GetSomethingRelatedToCallingAssembly() return in a member of ClassToResolve, then it always succeeds. It seems really weird to me ?!?

Thank you for your feedback if you can explain what's happening.

Regards

Clement

Sep 17, 2011 at 6:28 AM

The difference between DEBUG and RELEASE is that RELEASE does not include the .pdb files. Those files contain a lot of extra meta data. I'm no reflection expert but I know I ran into a similar issues once with StackTrace.