Chase Florell
Chase Florell

Reputation: 47417

How to make this Reflection work with WinRT

Reflection for Windows Store / WinRT applications is different than what I'm used to. How do I refactor this code block to work with WinRT?

note: This block of code WORKS in a PCL that does not target Windows Store applications. (Profile104). As soon as I change the target to Profile158, it won't compile any longer.

var migrationInterfaceType = typeof (IMigration);
var migrations =
    migrationInterfaceType.Assembly.GetTypes()
                          .Where(type => migrationInterfaceType.IsAssignableFrom(type) && !type.IsAbstract)
                          .OrderBy(type => type.Name);

// Cannot resolve symbol 'Assembly'
// Cannot resolve symbol 'IsAssignableFrom'

Essentially we have an interface called IMigration. Then we have an abstract class (Migration) that inherits IMigration. From there we create our migrations as follows.

public class Migration001 : Migration{

}

public class Migration002 : Migration{

}

// and so on.

What the code I'm struggling with needs to do is extract all of the Migrations into an IEnumerable<> so that I can loop over them and run them in order. As I said before, the first code block works when it's not targeting WinRT, but now that it needs to, it won't compile due to

// Cannot resolve symbol 'Assembly'
// Cannot resolve symbol 'IsAssignableFrom'

I have attempted two different approaches, but both yield no results in the IEnumberable<>

Failed attempt ONE

var migrations =
    typeof(IMigration).GetTypeInfo().Assembly.DefinedTypes
                          .Where(type => type.IsSubclassOf(typeof(IMigration)) && !type.IsAbstract)
                          .OrderBy(type => type.Name);

// enumeration yielded no results

Failed attempt TWO

var migrationInterfaceType = typeof (IMigration);
var migrations = migrationInterfaceType.GetTypeInfo().Assembly.DefinedTypes
                          .Where(type => migrationInterfaceType.GetTypeInfo().IsSubclassOf(type.GetType()) && !type.IsAbstract)
                          .OrderBy(type => type.Name);

// enumeration yielded no results

And just in case you're wondering, here's how I'm running the migrations... nothing special.

foreach (var migration in migrations)
{
    Run(_serviceLocator.GetInstance<IMigration>(migration.Name));
}

Upvotes: 0

Views: 415

Answers (3)

chamamo
chamamo

Reputation: 280

There is an extension method called GetTypeInfo to do that:

using System.Reflection;

.....

var migrationInterfaceType = typeof (Migration);
var migrations =
    migrationInterfaceType.GetTypeInfo().Assembly.ExportedTypes
                          .Where(type => migrationInterfaceType.GetTypeInfo().IsSubclassOf(type) && !type.IsAbstract)
                          .OrderBy(type => type.Name);

Upvotes: 0

Chase Florell
Chase Florell

Reputation: 47417

Trial and error lead to this. I do wish it was a little more clear :(

var currentAssembly = GetType().GetTypeInfo().Assembly;
var migrations = currentAssembly.DefinedTypes
                                .Where( type => type.ImplementedInterfaces
                                                    .Any(inter => inter == typeof (IMigration)) && !type.IsAbstract )
                                .OrderBy( type => type.Name );

Upvotes: 2

CSharpie
CSharpie

Reputation: 9477

Try this:

var migrations = typeof(IMigration).GetTypeInfo()
                                   .Assembly
                                   .DefinedTypes
                                   .Where(type => type.GetInterfaces()
                                                      .Any(itf=> 
                                         itf == typeof(IMigration)) && 
                                         !type.IsAbstract)
                                   .OrderBy(type => type.Name);

Upvotes: 0

Related Questions