Search code examples
c#cilmono.cecil

Resolving whether assemblies are Silverlight or .NET using Mono.Cecil in a MSBuild task


I'm using Mono.Cecil from an MSBuild task, and I've encountered a problem with the way it resolves assemblies. It is picking up the .NET version of Prism instead of the Silverlight one. The .NET version of Prism does not contain Microsoft.Practices.Prism.Regions.Behaviors.TabControlRegionSyncBehavior, and therefore we can't resolve that type.

I'm performing the task on the intermediate output, so the referenced assemblies are not in that folder. The search path for assemblies is set in the MSBuild script to ReferencePath.

Mono.Cecil does name-based matching in this function:

AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable<string> directories, ReaderParameters parameters)
{
    var extensions = new [] { ".exe", ".dll" };
    foreach (var directory in directories) {
        foreach (var extension in extensions) {
            string file = Path.Combine (directory, name.Name + extension);
            if (File.Exists (file))
                return GetAssembly (file, parameters);
        }
    }
    return null;
}

Is there a way to get it to compare the runtime (Silverlight vs .NET)? Are there any other ways to work around the problem? Is it sensible to make it use the Metadata version?


Solution

  • What Cecil does to resolve .NET assemblies is more complex than that. The issue is that Cecil's DefaultAssemblyResolver, that you're trying to use, doesn't know how to resolve Silverlight assemblies. It only knows about stock .NET assemblies.

    See Stack Overflow question Mono.Cecil fails to process a Silverlight 5 assembly for an example of customization of the assembly resolution process.