Unity3D Windows Store – Part 3: Reflections

In the first two parts of this series, we’ve talked about how to build and run a Unity3D game targeting the Windows Store platform, and we took a look at the limitations of .NET for Windows Store apps and how to pass the Windows App Cert Kit tests with our game.

One of these major limitations is the .NET for Windows Store apps Reflections API. Many of the methods you’re used to call for accessing types and type information are not available here, so we were forced to re-write them for our current Windows Store game. In this article, I’d like to summarize our learnings, hoping that I can spare you some headaches in this regard.

Accessing basic type information

In .NET for Windows Store apps, some functionality of the System.Type class has moved to the System.Reflection.TypeInfo class. The official explanation for this from the .NET documentation is as follows:

Type object represents a reference to a type definition, whereas a TypeInfo object represents the type definition itself. This enables you to manipulate Type objects without necessarily requiring the runtime to load the assembly they reference. Getting the associated TypeInfo object forces the assembly to load.

So basically, many things you were used to do with Type objects need to be done with the associated TypeInfo objects now:

 Retrieving all loaded assemblies

One might think that this might be a fairly easy task. Usually, you can refer to the current app domain using the static property System.AppDomain.CurrentDomain and call the System.AppDomain.GetAssemblies method to access a list of all assemblies that are currently available. As we learned in the previous part of this series, there’s a workaround out there on StackOverflow. This approach uses File I/O to find all libraries in the install location of your app, loads these libraries, and refers to the loaded types of those. Obviously, doing so every time results in an immense performance hit, so you’re better off caching these assemblies, which are very unlikely to change during app run-time anyway. Furthermore, trying to load an assembly for which the C++ compiler stripped the relocation addresses, such as Unity dlls, fails with a BadImageFormatException you might want to catch. Our final solution, getting rid of the nasty async keyword, looks like this:

 Finding a type by name

Sounds even easier than the previous one, doesn’t it? We first ran into issues doing so in the general .NET framework when we started using multiple assemblies in a single project. The default Type.GetType method requires you to pass the assembly-qualified name for finding a type. However, in our project, we were

  • storing some type names in XML data files for instantiating these types at runtime, and
  • automatically increasing the assembly version in each build.

Thus, every build would have invalidated all of our data files, because the assembly-qualified name would have changed due to the new version number. Thus, we were using Assembly.GetType instead, just passing the namespace-qualified name of the type we wanted to look up. With .NET for Windows Store apps, finding all assemblies was a problem, but we solved that in the last section. Finally, we wanted to get rid of the version, culture and public key token of all types that were used as type parameters for generic types (e.g. System.Collections.Generic.List`1[[System.Int32,mscorlib, Version=2.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089]]). Doing so with regular expressions was crazy slow on our Windows RT devices, so we’re doing that the good ol’ substring way now:

 Accessing the members of a type

Finally, if you wanted to get the field, property or method of a type, you’ve been using the Type.GetField, Type.GetProperty and Type.GetMethod methods before, respectively. In .NET for Windows Store apps, none of these is available. The TypeInfo class mentioned before offers a method called System.Reflection.TypeInfo.GetDeclaredField, and similar methods for properties and methods, but these don’t look for the specified members in the base types of the type you’re accessing. Thus, you’re forced to recursively look up the member in the base types yourself:

As always, feel free to share your thoughts or ask any questions in the comments below!

Author: npruehs

Nick Pruehs is a Co-Founder of Slash Games, Hamburg. In 2009, he graduated as “Best Bachelor” in computer science at Kiel University. Two years later Nick finished his master’s degree in “Sound, Vision, Games” at Hamburg University of Applied Sciences, becoming the Lead Programmer of Daedalic Entertainment shortly after.

7 thoughts on “Unity3D Windows Store – Part 3: Reflections”

    1. Hey Ufuk! Yes, this is indeed code for a Windows Store apps class library, which can be used as Unity plugin for Windows Store games. In MonoDevelop, in other words on the Unity side, you can safely use most of the methods from the Type class, i.e. Type.IsEnum, Type.IsValueType, and so on.

        1. Hey Ufuk,
          Have you added anything else to that code lately? I’m having a really hard time trying to port an old and extensive code of mine to run on Windows Phone 8. I’ve already written a lot of adaptations and extensions but, since Unity does not accuse where the compilation error is, it’s being like blind programming and I’m yet to make it work. I must be missing something(s).

          1. Hey Felipe, can you provide any more details, like screenshots of the builds errors? Also, are the errors occurring when building the player in Unity, when building the game in Visual Studio, or when running the app?

  1. Hi, npruehs! The error happens when building in Unity. Instead of telling me where in the code the error is, it just gives me a generic error message, telling me there is some problem in Assembly-CSharp.dll. It’s the exact same error the OP in this thread describes:

    http://answers.unity3d.com/questions/543183/error-while-creating-wp8-build.html

    A friend of mine had the same issue in his app, but since he was just starting the project he could solve the problem by creating extensions to the Reflection methods he used that would only compile when building to METRO. Since the dll error is generic, he did this by trial and error, but following his method is showing to be an impossible way for me since my code is pretty extensive and filled with Reflection and other types of System calls spread throughout the code.

    The problem gets even worse by the fact that there seems to be some other random methods that do not work on WP8 – for instance, my friend found out that ‘char.Parse(string)’ does not work, too. Who knows what other kinds of stuff could be not supported, and how could I find them if the compiler does not show me where the errors are?

    In the thread I mentioned, Thomas GF told he could find where his errors were by using some tool called .NET Reflector, but I couldn’t get it to work yet. This seems to be the better solution so far, though (if I can make it work at least hehe).

    1. Hey Felipe! I highly suggest filing a bug report, as this is clearly a Unity bug and nothing you should be required to dig into by yourself. Unity has fixed a handful of Metro bugs for me as well, and as your problem has a reproducibility of 100%, it shouldn’t take long for them.

      Apart from that, if you’re in a hurry, I can only suggest the “binary search” approach :/ Create a new, empty project and add your scripts (without any other assets). Try to build, and remove half of the scripts if it fails.

      Plus: I’m pretty sure you’ll be forced to refactor your Reflection API calls into a utility class, as Metro Reflections really works different from all other platforms. By encapsulating all of these calls in a single class, we were finally able to properly use Reflections across all platforms. I’m gonna send you an e-mail in a minute with the scripts, maybe it can speed up that process a bit for you.

Questions? Comments? Suggestions? Your turn! :)