Linq async interface without EF Core

Viewed 215

Let's say I have a query in EF Core that looks like so:

MethodWithDomainLogic() {
  return this.dbContext.People.Where(...).ToListAsync();
}

Now, in an effort to decouple my domain layer from my data access layer, I want this method to be in my domain assembly and that assembly not to have a reference to EFCore. So it would look like:

In Domain Layer:

public interface IEntities {
  IQueryable<Person> People { get; set; }
}

In Data Layer:

private IEntities entities; // injected with a dbcontext that implements the IEntities interface.

public Task<IEnumerable<Person>> MethodWithDomainLogic() {
  return this.entities.People.Where(...).ToListAsync(); // How to do this without referencing EFCore?
}

From my understanding, this is impossible since Linq does not support async queries on it's own.

I have solved this by setting up an interface of my own in the domain layer with the EFCore interface (basically copied and pasted the methods like ToListAsync and FirstAsync and etc...) and then implement it in my data layer with just a call to the EFCore version of this. However, that is very messy and complicated.

Is there a better solution? I want my domain method to use async programming and Linq without EFCore but for that Linq/async programming to be implemented with EFCore in the data layer.

1 Answers

Many of the query methods that you will need to use from your domain layer are defined in EF, not elsewhere in the framework. ToListAsync(), Include(navprop), AsNoTracking(), etc.

If you are composing queries in your domain layer, as you definitely should, and you want to access the full range of useful EF funtionality, you need a reference to EF.

It's possible to not have a reference to EF, and just use the subset of IQueryable<T> extension methods defined in the base framework, but that has a cost. And it's possible to put some sort of custom intermediate API between your domain and EF, but again the question is whether it's worth the effort.

Related