Home > Enterprise >  Designing a class using IOptions<T> being handled by EF?
Designing a class using IOptions<T> being handled by EF?

Time:09-17

I have a class carrying some info that I store in the DB.

class SomeThing
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public string Info => "extra info";
}

Naturally, the last property is omitted by EF by entity.Ignore(a => a.Info);. Now, I'd like the text extra info to be settable from appsettings.json, so I introduced an option provider and injected that using constructor (after registering it in Startup.cs). DI requires me to use a parametrized constructor while EF requires a parameterless one, so my class becomes a bit clogged.

class SomeThing
{
  private IOptions<Config> Config { get; }

  public SomeThing() { }
  
  public SomeThing(IOptions<Config> config)
  { 
    Config = config;
  }

  public Guid Id { get; set; }
  public string Name { get; set; }
  public string Info => Config.Value.Info;
}

Now, the clunky complexity makes me suspect that my design is flawed. Also, I don't see how EF is supposed to inject the value of the options, since it relies on the parameterless constructor. I considered implementing the empty constructor and fetch the services somehow, manually fetching the value, but that's a huge red flag in my opinion.

How should I approach the design of such a class?

CodePudding user response:

Regardless of this being a questionable design decision, you should delegate this work to a repository class.

ThingRepo.GetSomeThing() fetches the entity and populates Info property if needed. It can then inject IOptions<T> in the constructor.

class ThingRepo
{
    private Config _config;
    private DbContext _db;

    public ThingRepo(IOptions<Config> config, DbContext db)
    {
        _db = db;
        _config = config.Value;
    }

    public async Task<Thing> GetSomeThing()
    {
        var thing = await _db.Set<Thing>().FirstAsync();
        thing.Info = _config.Info;
        return thing;
    }
}

This circumvents the limitation of having to require IOptions<T> in entity constructor.

CodePudding user response:

As SomeThing is an entity definition for your database, i'd avoid trying to use DI to inject options into. I don't think its a supported scenario in EF Core anyway.

If you really need access to the Info object you could reference a different service that is DI compatible, but then again would it not be easier to access that directly from what ever code your calling to access Info from SomeThing

Typically EF core is for storing data in a database.

  • Related