Le eccezioni personalizzate devono vivere con l'interfaccia o l'implementazione?

4

Ho un'interfaccia IMyService in una libreria di classi.

Ho un'implementazione di questa interfaccia MyService in una libreria di classi separata.

MyService può aumentare un'eccezione personalizzata CustomException .

Dovrebbe CustomException vivere nella libreria di classi interfaccia , o nella implementazione della libreria di classi?

    
posta James 07.08.2018 - 10:02
fonte

4 risposte

6

Dipende dal significato / contesto dell'eccezione.

Ad esempio, il progetto corrente su cui sto lavorando utilizza una classe BusinessException . Questo è usato per ogni eccezione esplicitamente generata con un messaggio (in più livelli oltre al BLL - Sono consapevole che il nome è fuorviante). Il BusinessException risiede quindi nel livello del dominio (= dove IMyService si trova).

Per coloro che sono interessati, il motivo principale per usare BusinessException è che permettiamo che questi messaggi di eccezione vengano restituiti al consumatore della nostra API Web, mentre tutte le altre eccezioni vengono riformulate in "si è verificato un errore".

Una delle nostre classi di business logic ha un UserIsInactiveException particolare. Questa particolare eccezione viene utilizzata solo come regola di business logic particolare (agli utenti non attivi non è consentito aggiornare i dati). Pertanto, sappiamo intrinsecamente che verrà utilizzato solo sul livello della logica di business e quindi risiede nel progetto BLL (= dove si trova MyService ).

UserIsInactiveException eredita da BusinessException . Ma la posizione delle eccezioni sarebbe la stessa indipendentemente dal fatto che abbiano un'eredità o meno.

My own thoughts on this are that the exception should probably live with the implementation, as the exception is most likely an implementation detail.

Quello che dici non è errato, ma non è nemmeno universalmente applicabile. Alcune eccezioni fanno parte del framework più di quanto non siano un dettaglio di implementazione, ad esempio quando si prevede che il framework gestisca alcune eccezioni (personalizzate) in modo diverso.

    
risposta data 07.08.2018 - 10:38
fonte
3

Should CustomException live in the interface class library, or the implementation class library?

Prevedi che tutte le implementazioni di IMyService dovrebbero supportare il lancio di CustomException o solo MyService ?

Se il primo, lo metti nella libreria dell'interfaccia, quindi è accessibile a tutte le implementazioni.

Se quest'ultimo, allora c'è un'ulteriore decisione da prendere. Il resto della app, salvo il codice associato all'iniezione delle dipendenze, tratta solo IMyService ? In tal caso, dovresti inserirla nuovamente nella libreria delle interfacce, altrimenti le altre parti del codice devono fare riferimento alla libreria di implementazione solo per ottenere un riferimento all'eccezione.

Se la risposta è no, o che la libreria di implementazione deve essere referenziata per altri motivi, inseriscila nella libreria di implementazione, in modo che sia collocata nella classe che la lancia.

    
risposta data 07.08.2018 - 10:11
fonte
2

Vado con "Mantieni eccezioni personalizzate con l'implementazione anziché con l'interfaccia"

Inserendo le eccezioni personalizzate nella libreria di interfaccia si sta implicando che fanno parte del contratto che l'interfaccia applica. Se C # lo supporta, andresti oltre e specifichi throws su ogni metodo come Java.

Tuttavia, ritengo che questo approccio sia difettoso. Implica che l'eccezione personalizzata sarà nota chiamando il codice e l'unica ragione per cui sarebbe di usarli per il controllo del flusso. Una COSA MALE riconosciuta (tm)

Inoltre possiamo facilmente immaginare esempi in cui ogni implementazione vorrebbe esporre le proprie eccezioni personalizzate.

Considera un IRepository , con le implementazioni Repository_Database e Repository_Files . Entrambe le implementazioni vorrebbe per loro natura generare eccezioni relative alle loro implementazioni sottostanti, "Impossibile connettersi al database", "Impossibile aprire il file" ecc.

Piuttosto che cercare di forzare questi repository a catturare e lanciare un'eccezione generica "Cant initiate", che il codice chiamante utilizzerà per il controllo del flusso, aggiungerei una proprietà Open method / IsOpen all'interfaccia del repository , dovrebbe essere qualcosa che le implementazioni devono esporre.

    
risposta data 07.08.2018 - 10:41
fonte
0

Should CustomException live in the interface class library, or the implementation class library?

Sì, certo! Se ciò si verifica perché è un comportamento comune del processo, è necessario includere l'istruzione dell'eccezione come commento nella parte superiore del codice del metodo. Ti consiglio di includerlo nell'interfaccia. La documentazione per il tuo metodo sarà simile a questa:

///<sumary>
/// Method's description
///</sumary>
///<exception cref="CustomException">Occurs when an incident happens</exception>
    
risposta data 08.08.2018 - 13:51
fonte

Leggi altre domande sui tag