"but then I need to create some class to invoke all these classes,
wouldn't it violate the single responsibility principle?"
Penso di vedere qual è la causa della tua confusione; questo non è di per sé una violazione dell'SRP, perché la classe introdotta di recente è non effettivamente responsabile per i comportamenti implementati dalle altre classi.
Riceve semplicemente alcune richieste di alto livello e inoltra (parti di) il lavoro a quelle altre classi. La sua responsabilità è di coordinare la loro interazione in qualche modo.
Una delle motivazioni chiave alla base di SRP è evitare interdipendenze tra parti del codice che gestiscono ogni responsabilità (se è tutto nella stessa classe, il codice può essere ingarbugliato in modi sottili). Avere a disposizione interfacce pubbliche separate e ben definite 1 aiuta, poiché nasconde i dettagli dell'implementazione e limita / struttura i modi in cui queste classi possono interagire - in modo che una richiesta di modifica che riguarda solo una delle le classi hanno un effetto limitato (o, idealmente, nessun effetto) sugli altri.
1 Non intendo necessariamente tipi di interfaccia C # o Java.