0

We're having a serious issue with a custom generic type throwing exceptions related to serialization. Here's an example class:

internal class Foo<T> : IFoo<T>
{
    public void Bar(T tralalala)
    {
        //do whatever
    }
}

Now, we're using the Prism framework and its built-in SessionStateService to save the app state when it gets shut down or suspended. The problem is, when Prism attempts to bring back the app state after re-launch, an exception is thrown:

System.Runtime.Serialization.InvalidDataContractException
SerializationCodeIsMissingForType, Utilities.Foo.Foo`1[T]

I am well aware that in order for the serializer/deserializer to work, the .NET Native compiler needs extra metadata provided for the type, as marked in the rd.xml files. The problem is, I'm out of ideas how to mark that type. I thought a general tag for the whole namespace would work:

 <Namespace Name="Utilities.Foo" Dynamic="Required All" DataContractSerializer="Required All" />

But that's not the case, and I can't really find any examples of how to mark a generic type correctly. Since that serialization/deserialization issue makes passing the WACK test impossible, we really need to solve the problem. Help me, Stack Overflow, you're my only hope.

  • 1
    I've ping'd some folks from the .NET serializer team. I'm sure we can get you squared away. For things like this you can always shoot us mail at dotnetnative@microsoft.com. Happy to help! – MattWhilden Sep 09 '16 at 05:02
  • Does the issue happen when you compile your app with or without .NET Native tool chain? – X-Mao Sep 09 '16 at 17:29

1 Answers1

0

You can use <TypeInstantiation> element for setting reflection policy to constructed generic types. See https://msdn.microsoft.com/en-us/library/dn627487(v=vs.110).aspx for details.

For example, here's the rd.xml file I had for Foo,

<?xml version="1.0" encoding="utf-8" ?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Application>
    <Assembly Name="*Application*" Dynamic="Required All" />
    <TypeInstantiation Name="Foo"
                        Arguments="System.Int32"
                        DataContractSerializer="Required All" />
    <TypeInstantiation Name="Foo"
                        Arguments="System.String"
                        DataContractSerializer="Required All" />
  </Application>
</Directives>

My test app tested Foo<int> and Foo<string>, so I had two TypeInstantiation entries with different Arguments attribute values as shown above.

Or you can use the element below to apply the policy to all Foo<T> types,

<TypeInstantiation Name="Foo" DataContractSerializer="Required All" />

Note that the element does not have Arguments attribute.

X-Mao
  • 509
  • 3
  • 10
  • I'd like to add some extra context, since I've spent quite some time on the issue. – Jędrzej Jusza Oct 20 '16 at 12:27
  • And I've actually managed to send it before finishing my comment. The case here was more complicated - we've been using our own implementation of Weak Event pattern, rather reflection-heavy - attempting to serialize that would cause the SessionStateService to go haywire. We've switched it to a WeakEventListener from the UWP Toolkit and it's fine now. The example above was helpful with other generic types, so thanks a lot. – Jędrzej Jusza Oct 20 '16 at 12:29