Reputation: 47417
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
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
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
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