Determining the referenced assemblies of a Roslyn AssemblySymbol

When using reflection, it’s trivial to determine the assemblies that are required (referenced) by that assembly. You just use AssemblyInfo.GetReferencedAssemblies(). However, if using Roslyn, it’s not even possible to obtain the referenced assemblies of an AssemblySymbol, at least not via Roslyn. Instead, you must fall back to reflection to solve this problem.

So consider you have an IProject, a Compilation, and you want to determine, for each AssemblySymbol, what AssemblySymbols are referenced by that assembly. While not straightforward, this is still pretty easy to do. Ultimately, you need to combine both reflection and Roslyn to obtain the desired results:

public Dictionary<AssemblySymbol, AssemblySymbol[]> GetAssemblyReferences(
    IProject project, Compilation compilation)
{
    var assemblyInfoByAssemblySymbol = project.MetadataReferences
        .ToDictionary(
            x => compilation.GetReferencedAssemblySymbol(x), 
            x => Assembly.ReflectionOnlyLoadFrom(x.Display));
    var referencedAssembliesByAssemblySymbol = assemblyInfoByAssemblySymbol
        .ToDictionary(
            x => x.Key, 
            x => x.Value.GetReferencedAssemblies().Select(y => y.Name));
    return referencedAssembliesByAssemblySymbol;
}

Now, given any project/compilation, you can obtain a map between AssemblySymbol and its dependencies.

UIFormattedLabel - A Monotouch iOS souped up label that allows word-independent styling and hyperlinking

At my current gig, we had a need for a UILabel that allowed for the following features:

  • Giving different words and phrases a different color from the surrounding text.
  • Allowing some words to appear like a hyperlink, and attach an Action event to such words that can respond to those words being tapped.
  • Indicate a maximum number of lines for the label, and if the text would exceed this limit, to then render the last line with a trailing ellipsis.

Those were the hard requirements, but in the end, I’ve written a control that allows for the following independently modified (as in, each word can potentially have their own set of stylings) attributes:

  • Text color
  • Font (and thus font size, bold, italics, etc.)
  • Text decoration (underline, strikethrough)
  • Tap events (underline a word and respond to when the user taps on it)
  • Text alignment (standard “paragraph” alignment options of left, right, and center)
  • Maximum lines (when surpassed, an ellipsis will be rendered at the end of the max line)

The source code can be found at Github, which includes a sample project that produces the screenshot to the right.

Returning a string from a C# callback to C

I had a pretty difficult time finding a good example of returning a string from C# to C in a callback. For our application, we have the core game mechanism written in a C library, but I would like to implement as much non-game functionality in C# (MonoTouch, etc.) since C# is a much richer language.

One feature I want to move from the C library to C# is the logic for determining the path for files to assets. There’s a good deal of logic I’d like to apply on where assets live, and I don’t want that logic to have to be implemented in C. To that end, I defined a callback in the C library. The header looks like:

typedef void (*ContentFilePathProvider)(const char* file, char* buffer, int bufferSize);
extern void SetContentFilePathProvider(ContentFilePathProvider contentFilePathProvider);
void GetContentFilePath(const char* file, char* buffer, int bufferSize);

Here we expect the C# code to import SetContentFilePathProvider and invoke it passing it a (static) method defined in C# to implement calculating the fully qualified path to an arbitrary file. The type of the delegate is dictated by the ContentFilePathProvider typedef. And on the C side, whenever we want the fully qualified path, we just call GetContentFilePath.

Before looking at the C# implementation, let’s finish with the C implementation. First we need to create a global variable to store the callback:

static ContentFilePathProvider _ContentFilePathProvider = NULL;

The function to set the callback (called from C#):

void SetContentFilePathProvider(ContentFilePathProvider contentFilePathProvider)
{
    _ContentFilePathProvider = contentFilePathProvider;
}

This function is called anywhere in C we need to get the content file path for an asset:

void GetContentFilePath(const char* file, char* buffer, int bufferSize)
{
    _ContentFilePathProvider(file, buffer, bufferSize);
}

For example, elsewhere in our code, we have:

char fullPath[512] = {0};
GetContentFilePath(fileName, fullPath, 512);
return Foo(fullPath);

We initialize the buffer to 512 bytes. This means the callback must ensure it does not stuff more than 512 bytes of path into it. Obviously this number might need to be tweaked. That is life in the unmanaged world.

Now, let’s take a look at the C# impementation of the above contract. You’ll need to import the C function for setting the callback, but first we need to specify the delegate type for the callback:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ContentFilePathProvider(string file, IntPtr buffer, int bufferLength);

I’m using a standard unmanaged C lib produced in Xcode, so the calling convention is Cdecl. The second parameter, buffer, is what really tripped me up.

The Google seemed to indicate it should be of type StringBuilder. I tried this but the result on the C side was that the text was gobbledygook. Clearly something wasn’t right. Eventaully I found a terrific answer by Olivier Levrey on codeproject that led me to a working solution that uses IntPtr.

The last parameter indicates to the callee how much space there actually is in the buffer. You generally need the length of buffers in order to operate on them, if for overflow checking if nothing else.

Finally, the callback setter itself:

[DllImport(ImportSource)]
private static unsafe extern void SetContentFilePathProvider(
    ContentFilePathProvider contentFilePathProvider);

The code to implement this is a bit cumbersome, but works fine:

[MonoPInvokeCallback(typeof(ContentFilePathProvider))]
internal static void GetContentFilePath(string file, IntPtr buffer, int bufferLength)
{
    var s = Config.ContentDir + Path.DirectorySeparatorChar + file;
    if (s.Length &gt; bufferLength)
        throw new InvalidOperationException("File path is greater than length of buffer (" + 
            bufferLength + ")");
    // Convert from managed to unmanaged string
    IntPtr sPtr = Marshal.StringToHGlobalAnsi(s);
    // Create a byte array to receive the bytes of the unmanaged string
    var sBytes = new byte[s.Length + 1];
    // Copy the the bytes in the unmanaged string into the byte array
    Marshal.Copy(sPtr, sBytes, 0, s.Length);
    // Copy the bytes from the byte array into the buffer passed into this callback
    Marshal.Copy(sBytes, 0, buffer, sBytes.Length);
    // Free the unmanaged string
    Marshal.FreeHGlobal(sPtr);
}

The attribute up top (MonoPInvokeCallback) is extremely important if you intend to deploy to iOS. Without it you will get nasty AOT errors that will make you freak out. Especially since you will have otherwise tested this successfully in the simulator. And there is nothing that ruins my day more as when something works in the simulator but doesn’t work on the device.

And to assign the callback:

SetContentFilePathProvider(GetContentFilePath);

And that’s it! Now whenever our C code wants a file (and it might be located in one of many possible directories) the logic for finding that is happily implemented in C#. Once we figure out what the path is, we stuff it into a character array by way of explicit marshalling.

Getting the port from an NSUrl in MonoTouch

Unfortunately Xamarin.iOS (née MonoTouch) does not expose the port property on NSUrl. To get around that, add the following extension method to a utility static class of yours (such as NSUrlExtensions):

public static int? GetPort(this NSUrl url)
{
    NSValue port;
    if (typeof(NSUrl) == url.GetType())
    {
        port = NSNumber.ValueFromPointer(Messaging.IntPtr_objc_msgSend(url.Handle,
            Selector.GetHandle("port")));
    }
    else 
    {
        port = NSNumber.ValueFromPointer(Messaging.IntPtr_objc_msgSendSuper(url.SuperHandle, 
            Selector.GetHandle("port")));
    }
    using (port)
    {
        if (port.PointerValue == IntPtr.Zero)
            return null;
        else
            return (int)(NSNumber)port.NonretainedObjectValue;
    }
}

Now you can invoke url.GetPort() to obtain the port from a url. I think I got the conditional logic there correct — it should be if (url.IsDirectBinding) { ... } but unfortunately IsDirectBinding is protected and I didn’t really want to use reflection for this.

Update: Corrected the logic in the return statement to check for null and return a nullable int instead.

Loading a UIWebView offscreen

If you try to load a UIWebView offscreen (as in, before the web view has been added to any other views/controllers) in iOS 5.1, you might find that certain elements appear off screen.

We use Bootstrap, and the popups were showing up partially offscreen, as if the the perceived window size is wrong. To alleviate this problem, ensure that the Frame property of the UIWebView is set before trying to load the page.

Ending sentences with prepositions

This is not programming related, but it is about a personal project I’ve been working on: how to not end sentences with prepositions, and what is the point?

Recently I was documenting notes on how to configure an EC2 server from a fairly vanilla Rightscale template. In introducing the topic, I had written: (emphasis added)

I took the default Rightscale server template as a base. (not recommending this, as it’s misssing the monitoring stuff, but that’s what we derived these notes from.)

The topic of dicussion here is the clause:

but that’s what we derived these notes from

Contrast that with a sentence that actually follows that old preposition “rule”:

but that’s the template from which these notes are derived

In context:

I took the default Rightscale server template as a base. (not recommending this, as it’s misssing the monitoring stuff, but that’s the template from which these notes are derived.)

To me, the second option is dramatically more helpfully constructed and clear.

Thinking about the English language with this rule in mind has been one of the more instructive exercises I’ve undertaken with this beautiful language that I love.

Google Conversion Tracking for MonoTouch

I’ve created MonoTouch bindings for the Google Conversion Tracking SDK. You can just drop in the dll and add it to your project.

GoogleConversionPing.PingWithConversionId([conversionId], [label], 
    [price], [isRepeatable], [idfaOnly]);

Distributing iPhone Apps and Provisioning Profiles

When you start developing apps for iOS, you need a “provisioning profile.” When you first get started, you go through a tutorial, create a developer profile, download it, and use that when building your app.

However, when it comes time to distributing the app internally to your beta testers (or others), it’s easy to confuse yourself and believe that by adding people to your profile on Apple’s developer center, they can now download your app and install it. I had naively assumed that a network call would be made at install time to validate the user’s device against the profile on Apple servers. In hindsight, of couse it does not work this way.

Instead, the “right” to use your app is encapsulated entirely within the profile. This means if you want to allow a new device to use your app, you have to download the updated profile (after you’ve added the device on developer center) and use that profile in a new build of your app. In other words, it’s not possible to add people such that they can use an older version of your app. You will always have to generate a new build after adding devices to a profile.

Tags: ios

Using Entity Framework 5 code-first migrations with MySQL

I’ve created a fork of MySQL Data Connector v.6.6.4 that supports the latest version of Entity Framework (v.5).

To use it, you can just download the binaries, which are replacement assemblies for MySql.Data and MySql.Data.Entity. Also make sure your project is dependent on EF5 rather than 4.3.

After you Enable-Migrations the first time, modify your Configuration class’ constructor to include the line:

SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());

At this point, you should be able to run Add-Migration and Update-Database without issues.

The key changes of my fork are as follows:

  • The binaries are dependent on EF5 rather than EF4.3.

  • EF5 prepends dbo. to all of your table names, which MySQL cannot handle. Thus, my version hacks the SQL migration generator to strip out the dbo. prefix from the table names. This all assumes you are not overriding the schema via the TableAttribute on the entity classes.

  • It removes the usage of CreatedOn that was removed in EF5.

Android: Programmatically setting up selector drawables

If you want, for example, the icon on a tab to change based on whether it’s the selected tab or not, most examples you will find will require you to dirty your soul with XML like this:

<selector xmlns:android="http://schemas.android.com/apk/res/android">  
    <item android:state_selected="true" android:drawable="@drawable/iconselect"/>   
    <item android:drawable="@drawable/icon"/>        
</selector> 

Why is it that people enjoy defining logic and behavior in a medium other than a programming language? Using Java, our IDEs could help us write the code for this without having to check a manual. (Admitedly since Android chose to use integers for their states rather than a sensible enum, the IDE can’t help as much as we’d like.) Still, I prefer code. The equivalent to this garbage XML is to use the StateListDrawable class like this:

Drawable selectedIcon = getResources().getDrawable(R.drawable.iconselect);
Drawable defaultIcon = getResources().getDrawable(R.drawable.icon);
StateListDrawable selector = new StateListDrawable();
selector.AddState(new int[0], defaultIcon);
selector.AddState(new int[] { R.attribute.state_selected }, selectedIcon);

Notice how we use an empty integer array to represent the default (unselected) state. And we use the state_selected value to correlate with our selectedIcon.

Now that your selector drawable is set up, you can use it as your indicator:

getTabHost().newTabSpec("tab").setIndicator("Tab 1", selector);