How to avoid SerializationException: Type is not resolved for member XXX when testing a component that uses the LogicalCallContext
Asked Answered
B

1

33

I've recently started hitting the following exception in my unit test (NUnit) code when EF tries to load information from App.config:

System.Runtime.Serialization.SerializationException : Type is not resolved for member [my type name], [my assembly name]

This happens both with the NUnit GUI runner and with R#'s VS-integrated runner. Here's a quick unit test that reproduces the issue:

[Test]
public void Test()
{
    // adding 
    // ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    // here fixes things, probably because the configuration is cached

    CallContext.LogicalSetData("FooSlot", new Foo()); // removing this line fixes things
    ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // fails with above exception
}

[Serializable] // removing this gives a different exception complaining that Foo is not Serializable
public class Foo // : MarshalByRefObject // this fixes things
{ 
}

Using the fusion log viewer, I found that the failure was a result of a

FILE_NOT_FOUND HRESULT

error. Basically, it seems like opening the configuration somehow causes the Foo object to be sent back to the original (nunit runner) app domain, which then tries to load my assembly and can't find it because it's not in the bin folder. In fact, I confirmed that copying my assembly to the NUnit runner bin folder is another way to fix the issue.

At this point, it seems like using MarshalByRefObject is the best option. However, I'd love to here if there are better options and/or if someone can offer a thorough explanation of exactly what is going on and why. Are there any disadvantages to using MarshalByRefObject here?

This is different than this question, because I have already identified MarshalByRefObject as a potential solution and am trying to understand the problem in more depth / understand the implications of MarshalByRefObject. The answer to that post is just a callout to MarshalByRefObject with no useful additional detail.

Babbette answered 31/3, 2014 at 20:27 Comment(3)
Have a look at #8774314Clinquant
@Clint did you read to the end of my post? The answer to that question is just MarshalByRefObject, which I'm already asking about. I've updated the question with some additional detail on this.Babbette
@chasemedallion I'm having the same issue while running unit tests. In my scenario, I'm using dapper to access the database, using the Query method without parameters. This call will return an IEnumerable of Dynamic. The collection is then converted to a concrete set of objects and returned. The test runner then complains that the entity to I cast to is not marked as serializable, and this happens at the very end of the test method (on the closing curly brace). If I use the method Query of Dapper with the same type specified, the issue doesn't happen.Rehnberg
A
7

I think this is good explaination why you get this error.

Is it possible to use the logical call context within a unit test in VS 2010?

I searched what is good option this. I never find any answer except MarshalByRefObject. So why you should inherit your object with it . It is good explanation

Marshal By Value

Objects are only valid in the application domain where they are created. Any attempt to pass the object as a parameter or return it as a result will fail unless the object derives from MarshalByRefObject or is marked as Serializable. If the object is marked as Serializable, the object will automatically be serialized, transported from the one application domain to the other, and then deserialized to produce an exact copy of the object in the second application domain. This process is typically referred to as marshal by value.

This is source. It is good for Understading Object Serialization Concepts

https://msdn.microsoft.com/en-us/library/ms973893.aspx

Thank you this question I searched and learned good things.

Amorete answered 24/2, 2016 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.