Capire la catena di chiamate [chiuso]

1

Diciamo che ho un assemblyA che ha un metodo che crea un'istanza di assemblyB e ne chiama MethodFoo() .

Ora assemblyB crea anche un'istanza di assemblyC e chiama MethodFoo() .

Quindi non importa se inizio con assemblyB nel flusso di codice o con assemlyA , alla fine chiamiamo MethodFoo di AssemblyC() . La mia domanda è quando mi trovo in MethodFoo() come posso sapere chi mi ha chiamato? È stata una chiamata originariamente da assemblyA o era da assemlyB ?

Esiste un modello di progettazione o un buon modo OO per risolvere questo problema?

    
posta Blake 27.09.2012 - 17:18
fonte

3 risposte

1

Non sono a conoscenza di schemi generici o comuni nei linguaggi di programmazione. La maggior parte lo gestiscono tramite apposite API di reflection.

In .Net utilizza System.Diagnostics.StackFrame e Classi System.Diagnostics.StackTrace . Vedi link per un esempio. Altri linguaggi e ambienti potrebbero avere equivalenti.

    
risposta data 27.09.2012 - 17:20
fonte
3

Qui esco su un arto e suppongo che tu stia cercando tecniche orientate agli oggetti per implementare la strumentazione.

Ci sono due modi immediati che mi vengono in mente, il più comunemente usato sarebbe il primo a indovinare:

  1. Avere un globale (singleton o cosa hai) impila da qualche parte con cui si aggiunge immediatamente ogni metodo che esegue. mantenendo efficacemente una catena di chiamate globale. Potresti non dover fare un salto alla fine di ogni metodo che stai provando a usare, altre comuni pratiche di strumentazione sono di avviare un cronometro all'inizio del tuo metodo e fermarti alla fine per registrare la lunghezza ecc.

  2. Avere un framework di tipo DI che è un router per tutte le chiamate di metodo, che potrebbe comportarsi in modo simile al passaggio di messaggi e all'interno di questo framework si annotare in una pila ogni chiamata di metodo che si verifica in modo simile a sopra eccetto sarebbe centralizzato in questo posto.

Non posso dire di suggerire # 2 senza forse usare qualche framework AOP o qualcosa del genere, ma in generale, mantenere la propria traccia dello stack sul 100% delle chiamate al metodo è un po 'una strumentazione estrema ai miei occhi. Ottimo per eseguire il debug di tipo e forse necessario se non si sta lavorando in un linguaggio riflessivo, ma sarei sicuro di poter girare qualcosa del genere facilmente per la produzione e fare del mio meglio per tenerlo fuori mano, motivo per cui non mi piace molto il # 2 sopra.

Nessuno di questi è necessario all'interno di un linguaggio riflessivo e pertanto non dovrebbe essere implementato in C # tranne che per illustrare i confini del processo di attraversamento. (attenzione: potrebbe essere più veloce della riflessione se fatto bene, ma il costo di manutenzione continua a renderli non ne vale la pena)

    
risposta data 27.09.2012 - 17:40
fonte
3

IMHO dovresti chiederti seriamente perché pensi di aver bisogno di questo.

Se MethodFoo() si comporta diversamente se chiamato dall'assembly A o B, l'assembly di chiamata è qualcosa come un parametro di input nascosto a MethodFoo() e può probabilmente diventare la causa di comportamenti imprevisti o errati. Quindi, in alternativa, rendi esplicito questo parametro di input: aggiungi un parametro aggiuntivo a MethodFoo() che indica il contesto o il chiamante. Questo potrebbe essere un enum , un parametro string o un riferimento all'assembly chiamante stesso, in base alla modifica del comportamento previsto di MethodFoo() .

    
risposta data 27.09.2012 - 18:04
fonte

Leggi altre domande sui tag