mardi 29 juin 2021

Use Reflection to Find Interface

I'm not sure if it's the angle brackets that are causing me problems, but I'm having trouble coming up with an answer within the Stack Overflow answers. If there's one already out there, I'd welcome you to point me in the right direction.

To summarize, I have an Interface and I can't get reflection to find it. Let's set the stage:

Interfaces

interface ICrew
{
    string Name { get; set; }
}

interface IDataService<T>
{
    IEnumerable<T> GetItems();
}

Classes

class Crew : ICrew
{
    public string Name { get; set; }
}

class CrewRepository : IDataService<ICrew>
{
    DbContext _context { get; }

    public CrewRepository(DbContext context)
    {
        _context = context;
    }


    public IEnumerable<ICrew> GetItems()
    {
        return _context.Crews;
    }
}

class DbContext
{
    public DbContext()
    {
        Crews = new List<Crew>();
    }
        
    public List<Crew> Crews;
}

Code

class Program
{
    private static DbContext _context;

    static void Main(string[] args)
    {
        _context = new DbContext();

        //I want to find CrewRepository (which is type of IDataService<ICrew>)
        var dataService = Get(typeof(ICrew));
    }

    private static object Get(Type T)
    {
        var types = typeof(CrewRepository).Assembly.GetTypes();

        var test = types.Where(t => t.IsAssignableFrom(T)); //Finds ICrew

        var test2 = types.Where(t => t.GetInterfaces().Contains(T)); //Finds Crew

        var test3 = types.Where(t => t.GetInterfaces().Contains(typeof(IDataService<>))); //Finds nothing

        var test4 = types.Where(t => t.IsAssignableFrom(typeof(IDataService<>))); //Finds interface IDataService

        var test5 = types.Where(t => typeof(IDataService<>).IsAssignableFrom(t)); //Finds interface IDataService

        var instance = types
            .Where(t => t.IsAssignableFrom(T))
            .FirstOrDefault();

        if (instance != null)
        {
            return Activator.CreateInstance(instance, _context);
        }

        return default;
    }

}

I can't figure out how to query the Assembly Types correctly to get IDataService<T>. My Get method doesn't know what type it's going to be asked for until runtime, and generics inside of angle brackets are only able to be used if I know the type at compile time. Can anyone help me figure out what I should be doing here to get Get to return the correct class Repository that I'm hoping for by using reflection?





Aucun commentaire:

Enregistrer un commentaire