Attempt to access the method failed: System.Reflection.Emit.DynamicMethod

Jul 10, 2008 at 5:27 PM
Chris wrote very good post about Silverlight + Unity here. I was asking him the source code for that post last a few days ago but I didn't get any reply from him and I believe that he is so busy these days.

So, I decided to port Unity to Silverlight by myselft and I have converted ObjectBuilder and Unity project to Silverlight Class Libraries. But when I was testing, I'm facing some problems.

Here is the code that I used for testing Silverlight-version of Unity.

namespace SLUnityDemo {
    public interface ILogger {
        void Log(string value);
    }
}

namespace SLUnityDemo.Models {
    public class ConsoleLogger : ILogger {
        public void Log(string value) {
            Console.WriteLine(value);
        }
    }
}

public  void testButton_Click(object sender, RoutedEventArgs e)
        {
            IUnityContainer myContainer = new UnityContainer();
            myContainer.RegisterType<ILogger , ConsoleLogger  >();
            ILogger myLogger = myContainer.Resolve<ILogger>();

        }

I'm getting this error.

Resolution of the dependency failed, type = ILogger, name = . Exception message is: The current build operation (build key Build Key[SLUnityDemo.Models.ConsoleLogger, null]) failed: Attempt to access the method failed: System.Reflection.Emit.DynamicMethod..ctor(System.String, System.Type, System.Type[], System.Type) (Strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2)

I think it might be related to Security Issue of Silverlight. I think I need to make some methods as public but I'm not sure what I should change.

Any idea would be appreciated. Thanks.
Jul 10, 2008 at 6:15 PM
I am actually quite busy, so I apologize if your request got lost in the black hole of my email.

The fundamental issue you're running into is actually with the DynamicMethod class in the Silverlight CLR vs. desktop CLR. The constructor we're calling, the one that takes a Module as the last parameter, is not available in Silverlight. You have to change the call to the DynamicMethod constructor to use a different overload, the one that doesn't take a module. The down side of this change is that you cannot inject internal types in the Silverlight version due to the security model.

I've made some changes to our current internal version of the code to make the Silverlight port easier, but that won't be out for a little while. Thanks for giving this a try!

-Chris
Jul 11, 2008 at 5:27 AM
Edited Jul 11, 2008 at 5:41 AM
Thank you so much! Chris. My sample is working now. I'm trying to convert the StopLight example now. I will let you know the result soon.

I think my effort for converting Unity to Silverlight-compatible Unity will help Prism Contrib. I joined Prism Contrib project a few days ago and one team coordinator asked us to research Unity for Silverlight. If I can convert the StopLight Quick Start then I think we will be able to use it in Prism Contrib project. 

I'd like to ask you one thing.

Could you please share the equivalent Linq expressions of Array.Find, Array.FindAll, Array.ConvertAll and List<T>.RemoveAll? I wrote the following code for Find and FindAll but I'm looking for the better way.

Samples of Array.Find, Array.FindAll, Array.ConvertAll

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;

namespace Microsoft.Practices.ObjectBuilder2 {
    public static class ArrayHelper {
        public static T Find<T>(T[] array,
                Predicate<T> match) {

            foreach (var o in array) {
                if (match(o)) {
                    return o;
                }
            }

            return default(T);
        }
        public static T[] FindAll<T>(T[] array,
               Predicate<T> match) {

            List<T> list = new List<T>();
            foreach (var o in array) {
                if (match(o)) {
                    list.Add(o);
                }
            }

            return list.ToArray(); 
        }

        //forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1846607&SiteID=1
        public static TOutput[] ConvertAll<TInput, TOutput>(TInput[] array, Converter<TInput, TOutput> converter) {
            if (array == null) {
                throw new ArgumentNullException("array");
            }

            if (converter == null) {
                throw new ArgumentNullException("converter");
            }

            TOutput[] tempArray = new TOutput[array.Length];

            for (int i = 0; i < array.Length; i++) {
                tempArray[i] = converter(array[i]);
            }

            return tempArray;

        }
    }
}


Thanks.
Jul 11, 2008 at 6:04 AM
Hello Chris,

Yes. I have converted StopLight Quick Start to Silverlight. I have replaced Timer with DispatcherTimer in Silverlight.

But when I run the project, I'm getting this error.

Resolution of the dependency failed, type = StoplightView, name = . Exception message is: The current build operation (build key Build Key[StopLight.StoplightView, null]) failed: The value for the property "Presenter" could not be resolved. (Strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2)

Detailed Message ~

+        ex    {System.InvalidOperationException: The value for the property "Presenter" could not be resolved. ---> Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[StopLight.StoplightPresenter, null]) failed: The value for the property "Stoplight" could not be resolved. (Strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2) ---> System.InvalidOperationException: The value for the property "Stoplight" could not be resolved. ---> Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[StopLight.Logic.Stoplight, null]) failed: The value for the property "Logger" could not be resolved. (Strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2) ---> System.InvalidOperationException: The value for the property "Logger" could not be resolved. ---> Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[StopLight.ServiceImplementations.TraceLogger, null]) failed: Could not load type 'StopLight.ServiceImplementations.TraceLogger' from assembly 'StopLight, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. (Strategy type Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy, index 2) ---> System.TypeLoadException: Could not load type 'StopLight.ServiceImplementations.TraceLogger' from assembly 'StopLight, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
   at BuildUp_StopLight.ServiceImplementations.TraceLogger(IBuilderContext )
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   at Microsoft.Practices.SLUnity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
   at BuildUp_StopLight.Logic.Stoplight(IBuilderContext )
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodPropertySetterStrategy.ThrowOnFailedPropertyValueResolution(Exception inner, String propertyName)
   at BuildUp_StopLight.Logic.Stoplight(IBuilderContext )
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   at Microsoft.Practices.SLUnity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
   at BuildUp_StopLight.StoplightPresenter(IBuilderContext )
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodPropertySetterStrategy.ThrowOnFailedPropertyValueResolution(Exception inner, String propertyName)
   at BuildUp_StopLight.StoplightPresenter(IBuilderContext )
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)
   at Microsoft.Practices.SLUnity.ObjectBuilder.NamedTypeDependencyResolverPolicy.Resolve(IBuilderContext context)
   at BuildUp_StopLight.StoplightView(IBuilderContext )
   --- End of inner exception stack trace ---
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodPropertySetterStrategy.ThrowOnFailedPropertyValueResolution(Exception inner, String propertyName)
   at BuildUp_StopLight.StoplightView(IBuilderContext )
   at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
   at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)}    System.Exception {System.InvalidOperationException}


Could you please tell me how to solve this problem?
Jul 11, 2008 at 6:05 AM
Let's see. Should be something like the following (I haven't run these through the compiler):

Array.Find<T>(T[] array, Predicate<T> p) becomes:

T result = (from item in array where i => p(i) select item).FirstOrDefault();

Array.FindAll<T>(T[] array, Predicate<T> p) becomes:

T[] result = (from item in array where i => p(i) select item).ToArray();

Array.ConvertAll<TIn, TOut>(T[] array, Converter<TIn, TOut> convert) becomes:

TOut[] result = (from item in array select item => convert(item)).ToArray();

List<T>.RemoveAll doesn't have a Linq equivalent, because it mutates the underlying list rather than producing a new sequence. But List<T>.RemoveAll is supported on Silverlight, so you don't need to replace it.

Jul 11, 2008 at 6:09 AM
Oh!! I got it. I need to change "internal" to "public" in StopLight Sample.

Thanks a lot.. 

Jul 11, 2008 at 6:11 AM


ctavares wrote:
Let's see. Should be something like the following (I haven't run these through the compiler):

Array.Find<T>(T[] array, Predicate<T> p) becomes:

T result = (from item in array where i => p(i) select item).FirstOrDefault();

Array.FindAll<T>(T[] array, Predicate<T> p) becomes:

T[] result = (from item in array where i => p(i) select item).ToArray();

Array.ConvertAll<TIn, TOut>(T[] array, Converter<TIn, TOut> convert) becomes:

TOut[] result = (from item in array select item => convert(item)).ToArray();

List<T>.RemoveAll doesn't have a Linq equivalent, because it mutates the underlying list rather than producing a new sequence. But List<T>.RemoveAll is supported on Silverlight, so you don't need to replace it.



Hi Chris,

Okay. Thanks a lot for sharing. Can I contribute my converted version of Unity (I call it "SLUnity") and the StopLight sample in Silverlight to "Unity Contrib"?
Mar 22, 2009 at 2:32 PM
Yes. Syntax was bad but I give a lot of idea. Thanks. I posted the correct syntax and the rest of Array related function in this post. . Silverlight 3: Array Helper I want to create those methods like an extension method but it doesn't work somehow