In the same way as the preceding approach, you could divide the abstraction of domain service into two parts—main service abstraction and read-only service abstraction:
public abstract class ReadOnlyBaseService<TE, T> { private final Repository<TE, T> repository; ReadOnlyBaseService(ReadOnlyRepository<TE, T> repository) { this.repository = repository; } ... }
Now, we could use this ReadOnlyBaseService to create the BaseService. Here, we are using the dependency inject pattern via a constructor to map the concrete objects with abstraction:
public abstract class BaseService<TE, T> extends ReadOnlyBaseService<TE, T> { private final Repository<TE, T> _repository; BaseService(Repository<TE, T> repository) { super(repository); ...