views:

204

answers:

2

I am trying to resolve a TimeSpan using Unity. Executing the container Resolve call results in a FatalExecutionEngineError.

FatalExecutionEngineError was detected Message: The runtime has encountered a fatal error. The address of the error was at 0x543c3dc8, on thread 0x1bb8. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.

Running the test in DEBUG causes the following file to be requested by the debugger.

X:\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\DynamicMethodBuildPlan.cs

And it shows the following ExecutionEngineException on line 38.

System.ExecutionEngineException was unhandled Message="Exception of type 'System.ExecutionEngineException' was thrown." InnerException:

Test

[TestClass]
public class Example
{
    private readonly IUnityContainer container = new UnityContainer();

    [TestInitialize]
    public void TestInitialize()
    {
        container.Register<TimeSpan>(new ExternallyControlledLifetimeManager());
    }

    [TestMethod]
    public void Test()
    {
        var expected = new TimeSpan();
        var actual = container.Resolve<TimeSpan>();
        Assert.AreEqual(expected, actual);
    }
}
+1  A: 

I'm not sure why you get the error, but I tried to replace the type configuration (in the configuration file you edited out) with the following it works.

<instances>
   <add name="MyTimeSpan" type="System.TimeSpan" value="1.02:03:04"  />
</instances>

var duration = container.Resolve<TimeSpan>("MyTimeSpan");

The above should return a timespan with a duration of 1 day, 2 hours, 3 minutes and 4 seconds.

(I tried this with Unity 4.1)

Kim Major
I performed `container.RegisterInstance<TimeSpan>(TimeSpan.FromSeconds(10));` and that resolves fine.
Anthony Mastrean
A: 

Fatal Execution Engine Error when resolving a TimeSpan

I posted this issue on the Unity CodePlex site. It has been answered.

In current bits you get the proper "InvalidOperationException". TimeSpan has multiple constructors, and by default it picks the four-argument one, and then doesn't know what ints to supply. Structs don't actually have a zero-argument constructor, the clr "cheats" under the hood.

The solution is to tell Unity which constructor to use.

container.Register<TimeSpan>(new ExternallyControlledLifetimeManager(), 
    new InjectionConstructor(0L));
Anthony Mastrean
But I think the Register Instance solution is still the right one. It more accurately addresses the use of a TimeSpan in an IoC container.
Anthony Mastrean