0

I'm trying to get a property from an object by reflection.

public class CosmosDbSet<TEntity> : DbSet<TEntity> where TEntity : class, IEntity<string>
{
    public string Name { get; }
    //...
        );

}

public class SKCosmosDbContext : CosmosDBContext
{
    public CosmosDbSet<Item> Items { get; }

   public SKCosmosDbContext ()
   {
        Items = new CosmosDbSet<Item>(
            this,
            "Items"
        );
   }
    //...
}

public abstract class CosmosDBContext : DbContext
{
    public async Task EnsureContainersExistAsync()
    {
            var sets = GetType().GetProperties()
                .Where(pi => pi.PropertyType.IsGenericType
                    && pi.PropertyType.GetGenericTypeDefinition().Equals(typeof(CosmosDbSet<>))
                );
            foreach (var set in sets)
            {
                var value = set.GetValue(this, null); // => value is always null
                //...
            }
    }
}

public static class DbInitializer
{
    public async static Task InitializeAsync(IServiceProvider services, ILogger logger)
    {
        var dbContext = services.GetRequiredService<SKCosmosDbContext>();
        await dbContext.EnsureContainersExistAsync();
    }
}

As you can see, the property Items from SKCosmosDbContext has been found but, I can't have access to it. Description

How to have access to the property using reflection?

Cedric Arnould
  • 1,991
  • 4
  • 29
  • 49
  • 1
    Can you please provide a [mcve]? The most obvious explanation is that that property is actually `null`, and you haven't shown anything which demonstrates that this isn't the case – canton7 Jan 06 '22 at 16:28
  • Good point! I added the initialization of Items property in the constructor of SKCosmosDbContext in the post. About the minimal reproducible exemple, if I don't have any answers soon, I will try to create one. Thanks :) – Cedric Arnould Jan 06 '22 at 17:08
  • I wouldn't wait -- you fall off the "latest" list pretty quickly (your question is already hard to find), and the longer you leave it, the less likely it is that people will see it. You've realistically got a window of about 5-10 minutes to present a good question which others can answer, before interest moves to other questions. – canton7 Jan 06 '22 at 17:10
  • Good to know! Thanks :) – Cedric Arnould Jan 06 '22 at 18:01
  • 1
    You know what, you were true, currently the code doesnt enter in the constructor, so the Items is not initialized! Thanks! – Cedric Arnould Jan 06 '22 at 18:06

1 Answers1

0

So basically I see problem in using .GetGenericTypeDefinition() call. If you do more detailed debug you could see that it returns enumerable with next content: enter image description here

To get what you want you could use pi.PropertyType.GetGenericArguments()[0] and than use its return value to equal it in your linq query. ex. enter image description here

I used dummy types just for sake of example

Your problem could be related also with this one: Get type of generic list

TL;DR Example works after changing query to:

var sets = db.GetType().GetProperties()
            .Where(pi => pi.PropertyType.IsGenericType
                && pi.PropertyType.GetGenericArguments()[0].Equals(typeof(...))
            );
Duje Šarić
  • 29
  • 1
  • 4