I have some classes like this:
public class Customer
{ }
public interface IRepository
{ }
public class Repository<T> : IRepository
{ }
public class CustomerRepository<Customer>
{ }
Then, as per the answer to this question I can use reflection to get a list of types referenced by generics for each of my *Repository:
What I want to end up with is a Dictionary<Type, IRepository>
So far, I have this:
Dictionary<Type, IRepository> myRepositories = Assembly.GetAssembly(typeof(Repository<>))
.GetTypes()
.Where(typeof(IImporter).IsAssignableFrom)
.Where(x => x.BaseType != null && x.BaseType.GetGenericArguments().FirstOrDefault() != null)
.Select(
x =>
new { Key = x.BaseType != null ? x.BaseType.GetGenericArguments().FirstOrDefault() : null, Type = (IRepository)x })
.ToDictionary(x => x.Key, x => x.Type);
However, it doesn't like my cast (IRepository)x
I get the following error:
Unable to cast object of type 'System.RuntimeType' to type 'My.Namespace.IRepository'.
You cannot cast (IRepository) type with type is Type class,
you can use Activator.CreateInstance to create object CustomerRepository, you also don't need to use Select, instead, use ToDictionary directly, the code below:
var myRepositories = Assembly.GetAssembly(typeof(Repository<>))
.GetTypes()
.Where(x => x.BaseType != null &&
x.BaseType.GetGenericArguments().FirstOrDefault() != null)
.ToDictionary(x => x.BaseType.GetGenericArguments().FirstOrDefault(),
x => Activator.CreateInstance(x) as IRepository );
If x is a System.Type object, like if x is typeof(Repository<>), you can't just cast it like that. The Type is not an instantiation.
If x had no "free" type parameters, that is if x where non-generic or closed generic, then (IRepository)Activator.CreateInstance(x) might create you an object of type x. But I'm not sure that's what you need. Will there be a parameterless instance constructor?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With