Preventing Unity3D IL2CPP from stripping your code

I was trying to get a list of a type's constructors at runtime using reflection, so that I could create an instance of the class using dependency injection.

All worked just fine until we tried to build the app for iOS. At first we were using Mono as the scripting back-end, but it seems that new versions of iOS pop up a dialog telling the user the app is 32 bit and may run slowly (i.e. "Your app is crap"). When switching the backend scripting to IL2CPP (in File->Builder->Player Settings) the app suddenly wasn't working. It turns out that SomeType.GetConstructors().Count was returning zero, which was a problem because obviously I wanted to invoke those constructors with dependencies.

The problem was that because these constructors weren't being calling explicitly from anywhere in my app IL2CPP decided I didn't need them, and stripped them out.

The solution is to create a file in your Assets folder called link.xml and fill it in like so....

  <assembly fullname="Assembly-CSharp">
    <type fullname="Holovis.*" preserve="all"></type>

Assembly-CSharp is the default name created for all of your scripts by Unity. If you are using any others you need to prevent stripping on then you can add additional <assembly> nodes. As you can see from the example you can list types individually or use * as a wild card.  You can have multiple <type> nodes per <assembly> node.

Read this page from the manual for more information.


Forcing a device-orientation per scene in Unity3D

Unity3D has a Screen class with an orientation property that allows you to force orientation in code, which lets you have different scenes with different orientations (useful in mini-games). this works fine for Android but crashes on iOS.
The problem is the file UnityViewControllerBaseiOS.mm that gets generated during the build for iOS has an assert in it which inadvertently prevents this property from being used. It is possible to create a post-build class that runs after the iOS build files have been generated that can alter the generated code before you compile it in XCode.
Just create a C# script named iOSScreenOrientationFix.cs and paste in the following code - adapted from this Unity3D forum post.
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.IO;

namespace Holovis
    public class iOSScreenOrientationFix : MonoBehaviour
    // This method is added in the Advanced Features Settings on UCB
    // PostBuildProcessor.OnPostprocessBuildiOS
    public static void OnPostprocessBuildiOS (string exportPath)

        public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
            ProcessPostBuild(buildTarget, path);

        private static void ProcessPostBuild(BuildTarget buildTarget, string path)
            if (buildTarget == BuildTarget.iOS)
                Debug.Log("Patching iOS to allow setting orientation");
                string filePath = Path.Combine(path, "Classes");
                filePath = Path.Combine(filePath, "UI");
                filePath = Path.Combine(filePath, "UnityViewControllerBaseiOS.mm");

                Debug.Log("File Path for View Controller Class: " + filePath);

                string classFile = File.ReadAllText(filePath);

                string newClassFile = classFile.Replace("NSAssert(UnityShouldAutorotate()", "//NSAssert(UnityShouldAutorotate()");

                File.WriteAllText(filePath, newClassFile);
You can set it in a scene by attaching the following MonoBehaviour to a game object
using UnityEngine;

namespace Holovis
    public class SetDeviceOrientation : MonoBehaviour
        public ScreenOrientation orientation = ScreenOrientation.AutoRotation;

        void Awake()
            Screen.orientation = orientation;


A UI thread dispatcher for Unity3D

I've recently been working on implementing an IHttpService that can work outside of a MonoBehaviour and call out to web services asynchronously.

Rather than providing my IHttpService.JsonPost method with callbacks I decided to have it return a Promise, the code for which I took from this Real Serious Games GitHub repository.

The problem is that when you use WebClient's async methods they call back the Complete events on the worker thread, so code like this won't work because you cannot manipulate UI from any thread other than the main one.

  .Then(myInfo => someTextUiObject.text = myInfo.Name);
And there seems to be no kind of thread Dispatcher in Unity3D for UI updates as there is in Windows.Forms - so I wrote my own.

using System.Collections;
using System;
using System.Threading;
using System.Collections.Generic;
using UnityEngine;
public class UiThreadDispatcher : Singleton<MonoBehaviour>
    static volatile int lockValue = 0;
    static Queue<Action> actionQueue = new Queue<Action>();
    void Awake()
    public static void Dispatch(Action action)
    static void Lock()
        while (Interlocked.Exchange(ref lockValue, 1) != 0) { }
    static void Unlock()
        lockValue = 0;
    private IEnumerator CheckForDispatchedActions()
        while (true)
            Action action = null;
                while (actionQueue.Count > 0)
                    action = actionQueue.Dequeue();
            catch (Exception unexpectedException)
            yield return null;

The idea is that any piece of code can call the static Dispatch method, for example

//Instead of this
  .Then(myInfo => someTextUiObject.text = myInfo.Name);
//You would do this
  .Then(myInfo => UiThreadDispatcher.Dispatch(() => > someTextUiObject.text = myInfo.Name));
The Queue object needs to be locked to Enqueue/Dequeue items, but I use a simple SpinLock pattern because clashes will be very rare. Then I just have the MonoBehaviour instance execute the queued actions.

*Note to self: Must test on iOS.


NodeJS, Web-Express, and TypeScript from scratch

Over the past year I've been spending my time contracting for a company in Norway. Now that project is completed it is time for me to start playing again, so I thought I'd pick up an old Node Express project. This time I intend to use TypeScript instead of Javascript. I'd also like to write unit tests and dependency injection - both are something I'm very familiar with in the C# world, but not in Node. I'm going to use this blog to record what I did; I will undoubtedly revisit some of these posts and make changes as I learn.

In this first blog I intend to cover how to get up and running with Node, Express, and WebStorm (optional) from a fresh installation of Ubuntu Linux.

The first thing we need to do is use apt-get to install Node.
sudo apt-get install nodejs
I've noticed that some Linux apps will look for a command "node" and others will look for "nodejs", so after installing I want to make an alias so that both commands will work.
cd /usr/bin
sudo ln -s nodejs node
Next we need to install the package manager for Node. This allows us to reference 3rd party libraries (such as the Express web server) in our applications. It also keeps track of which specific versions we have used for different applications we have developed, so it's possible to have different apps running on different library versions and upgrade them independently of each other.
sudo apt-get install npm
With npm installed we can now get start to import our Node dependencies. These dependencies are used for getting a project up and running very quickly and so need to be installed as global packages, which means they will be available anywhere on your Linux installation by using the npm command. To install an npm package globally we need to use the -g option.
sudo npm install -g gulp
sudo npm install -g yo
sudo npm install -g generator-express-typescript
Gulp and Yo are both task automation applications. Gulp is used to compile (transpile) our TypeScript into JavaScript and then run our test web server, we can also use it to run automated unit tests. Yo is used to create the skeleton app that we will develop further, and generator-express-typescript is the template it will use to create it. So, make a folder, cd into it and type
yo express-typescript
Yo will ask if you wish to use gulp or grunt, choose gulp; when asked if you wish to create a Dockerfile select Yes.

Once the skeleton for our new application has been created type
The gulp command will look for a file named gulpfile.js - this is where we can create named tasks to run from the command line. If no command is specified, gulp will run the default task in the file, which is named 'default'.

You will see output similar to this
[10:51:12] Using gulpfile ~/source/yourapp/gulpfile.js
[10:51:12] Starting 'clean'...
[10:51:13] Finished 'clean' after 1.22 s
[10:51:13] Starting 'ts'...
[10:51:16] Finished 'ts' after 2.29 s
[10:51:16] Starting 'server:start'...
[10:51:16] Finished 'server:start' after 19 ms
[10:51:16] Starting 'default'...
[10:51:17] Finished 'default' after 942 ms
[10:51:17] Development server listening. (PID:52108)
You can now see your skeleton app by navigating to http://localhost:3000

Optional - Downloading WebStorm

As this part is optional I won't explain the steps. Downloading and running software should be simple enough.

  1. Download webstorm to your Downloads folder
  2. cd ~/Downloads
  3. tar -xvcf WebStorm[the rest of the download's file name]
  4. sudo mv ./WebStorm-....... /opt/webstorm
  5. /opt/webstorm/bin/webstorm.sh 

Using strongly typed libraries

One of the benefits of using TypeScript instead of JavaScript is that it is strongly typed. The problem is that not all libraries are written in TypeScript and so no type information is provided by default. Thankfully the Definitely Typed project has a huge collection of definition files to help us. They are implemented as a set of interfaces; TypeScript interfaces don't transpile to JavaScript, they are just for type safety checking.

By default the Yo express-typescript template adds some of these files, but it uses an out-of-date method of referencing them. So, the next thing we will do is to remove the strongly typed definition files for this project in order to add the newer ones using the new recommended approach.

  1. Delete the tsd.json file
  2. Delete the typings folder (type rm -r typings)
  3. Edit the /app.ts and /routes/index.ts files
Next we need to install the Node package "typings", we'll do this globally so that it is available as a standard npm command and can be used when creating new projects.
sudo npm install -g typings
Now make sure you are in the root of your project and initialise typings for it.
typings init 
Now instead of downloading Definitely Typed files and putting them somewhere in our project's sources we can search for libraries using the typings search command, and install them using the typings install command.

If you look in one of your project's TS files using an editor like WebStorm you will see that the require keyword is no longer recognised. This is because the typings folder we deleted contained library definitions to give us strongly typed information for Node itself. The first thing we want to do is to correct that. Type in the command

typings search node
This will show you all strongly typed definition files that match the search phrase. An important thing to pay attention to is the Source column. When installing one of these libraries we need to prefix its name with the value in that column, separated with a tilde. For example, the "node" entry has a source "dt", so it's fully qualified name for installing is "dt~node".

Whenever we are using the Definitely Typed libraries (source = dt) we need to add the --global option to our command line so typings knows to resort to those legacy files. We also want to include the --save option so that our typings.json file is updated.

typings install --global --save dt~node
Now if you look back at one of your TS files you should see the require keyword is now recognised!

By looking through dependencies section of the package.json file we can see which libraries Yo has specified are needed for this skeleton site, and install the typings for each of them. To save you some time, just copy/paste the following lines into your terminal window.

typings install --global --save dt~express (fixes Request/Response)
typings install --global --save dt~express-serve-static-core
typings install --global --save dt~serve-static
typings install --global --save dt~mimetypings install --global --save dt~q
typings install --global --save dt~underscore
typings install --global --save dt~mongoose
typings install --global --save dt~serve-favicon
typings install --global --save dt~morgan
typings install --global --save dt~cookie-parser
typings install --global --save dt~body-parser
Now, some of the packages in the package.json are listed under the devDependencies section. When installing these we need to use --save-dev rather than just --save, this will ensure they go into the development environment's requirement list rather than the runtime list.
typings install --global --save-dev dt~should
typings install --global --save-dev dt~superagent
typings install --global --save-dev env~mocha
typings install --save-dev debug
Note that the final dependency "debug" does not have the --global option specified. This is because when you do a typings search for "debug" you will see there are two entries. Once has a source of npm, and the other has a source of dt (Definitely Typed project). The npm one is newer so we want to use that one, and since npm is the default source we don't need the prefix~ before the name, and we don't need to specify --global to tell typings it needs to look through the Definitely Typed repository.


[Solved] MVCApplication Parser Error

I have this problem because I have to develop with VS running as administrator in order to use Local IIS hosting. When files are added (or generated by compiling) I think VS was setting the owner as Administrator, which IIS then cannot read. Start a command prompt as Administrator and type in the following
icacls c:\devpath\yourwebsite /grant everyone:(OI)(CI)F /T


How to Create a Self Signed Certificate in IIS 7

I know I am going to want this link again in the future!


VSTO Office plugin not appearing in Office 2007

If you have an office VSTO plugin that is working in other versions of Office but not appearing in Office 2007 then try setting the following registry value


Name = EnableLocalMachineVSTO
Value (DWORD) = 1


Watching a single property in an array in AngularJS

A typescript example that converts the array's property into a single string that can be watched.
            () => this.someArray.map(x => x.selected ? "1" : "0").join(""),
            (newValue, oldValue, scope) => this.onSelectionChanged(this.getSelectedItems()));

Getting an AngularJS directive to call back a method on its parent's controller

Here is a TypeScript example of how to call back a method on the controller from an embedded directive. The most important thing to note is that the directive's parameter name for your callback uses a & when defined, and when calling that callback you should not use positional parameters but instead use an object with properties having the names of the parameters in the target.
Register the directive when you create your app module:
module MyApp {
    var app: angular.IModule = angular.module("MyApp");
The registration code is as follows:
module MyApp.Directives.FileUploader {
  class FileUploaderDirective implements angular.IDirective {
      public restrict: string = "E";
      public templateUrl: string = "/app/Directives/FileUploader/FileUploaderDirective.html";

      //IMPORTANT - Use & to identify this as a method reference
      public scope: any = {
        onFileItemClicked: "&"
      public controller: string = "MyApp.Directives.FileUploader.Controller";
      public controllerAs: string = "controller";
      public bindToController: boolean = true;
      public transclude: boolean = true;
      public replace: boolean = true;

  export function register(app: angular.IModule) {
      app.controller("MyApp.Directives.FileUploader.Controller", Controller);
      app.directive("fileUploader", () => new FileUploaderDirective());
The directive's controller would look like this
module MyApp.Directives.FileUploader {
    export class Controller {
        public files: string[] = ["One", "Two", "Three"];
        //The callback specified in the view that created this directive instance
        public onFileItemClicked: (fileItem) => void;

        // This is the controller method called from its HTML's ng-click
        public fileItemClicked(fileItem) {
            //IMPORTANT: Don't use comma separated parameters,
            //instead use an object with property names to act as named parameters
                fileItem: fileItem
The directive's HTML would look something like this
  • ng-repeat="item in controller.files" ng-click="controller.onFileItemSelected(item)"> {{ item }}
  • The main view will have an instance of your directive like so
     ng-app="MyApp" ng-controller="MainController as controller">
    Now all you need on your MainController is a method
    public fileItemClicked(fileItem) {
      alert("Clicked " + fileItem);


    AngularJs - binding HTML

    The directive ng-bind will escape HTML to avoid data acting maliciously. If you want to output html you need to use ng-bind-html

    <div ng-bind-html="someHtmlBody"/>

    The important step to getting this working is to ensure the script angular-sanitize.js is referenced on your page, and it is specified as a dependency when creating a module....

    var app = angular.module("MyApp", ["ngSanitize", "OtherDependencies"]);

    AngularJS routes with ASP MVC Forms authentication

    The ASP MVC app I am working on uses forms authentication with a timeout. This means that when the session has timed out and the user clicks refresh they get redirected to a login page, and after that they get directed back to the original page without the deep-linked client-side # part of the url. 

    The solution to this is as follows:

    The first thing to do is to have the ASP MVC server side capture any URLs that should related to your client-side angular routing and return the single-page app HTML. When registering your ASP MVC routes add the following rule
                name: "Angular",
                url: "x/{*clientPath}",
    Where the "x/" is the base part of your client app, of course you can do without the "x" in the URL if your entire app is a single-page angular app, in which case you will need to add a preceding rule to render your ASP MVC server side account-login page.
    Then in your Angular app make sure you use Html5 mode, like so
    app.config(["$locationProvider", "$routeProvider", function ($locationProvider, $routeProvider) {
            enabled: true,
            requireBase: false,
            rewriteLinks: true
        $routeProvider.when("/x/docs/upload", {
        $routeProvider.when("/x/docs/view", {
            redirectTo: "/x/docs/upload"
    When you open your browser and navigate to http://mysite/x/what/ever/you/like the server side will use XController.Index to render Views\x\Index.cshtml, which will load your single page app, and then ngRoute will take over and present the relevant view for the "x/what/ever/you/like" part.