Contribuisco a un progetto open source che utilizza pesantemente il modello di progettazione iniezione-ctor. Recentemente, c'è stata una discussione sull'uso dell'intercettazione per alcune cose, tra cui l'iniezione di comandi dell'interfaccia utente a un modello di visualizzazione e il binding corretto del comando al valore corretto.
Ad esempio, abbiamo un comando:
public class FooCommand : CommandBase // CommandBase implements ICommand
{
public bool CanExecute(object obj);
public void Execute(object obj);
}
Ne abbiamo molti e li iniettiamo nel modello di visualizzazione con Ninject. Potrebbe essere rilevante il fatto che in questo caso specifico i comandi siano contrassegnati con un attributo, quindi sappiamo quale sottoinsieme deve essere iniettato:
public class FooViewModel : ViewModelBase
{
public FooViewModel(IEnumerable<CommandBase> commands) {}
}
Ora, nella classe definita sopra, procediamo in questo modo:
public class FooViewModel : ViewModelBase
{
public FooCommand FooCommand { get; }
public FooViewModel(IEnumerable<CommandBase> commands)
{
FooCommand = commands.SingleOrDefault(command => command is FooCommand);
}
}
L'istanza pubblica di FooCommand
è associata agli elementi dell'interfaccia per determinate azioni.
Ora, quando abbiamo provato a lavorare con questo usando i comandi intercettati, tutto si è rotto. Quando abbiamo intercettato la nostra implementazione e abbiamo iniettato l'implementazione di Ninject, abbiamo ricevuto solo un mucchio di implementazioni CommandBase
, quindi non sappiamo quale comando legare a quale valore. In sostanza, ci affidiamo a un'implementazione specifica oa qualsiasi implementazione derivata per associare a un comando specifico; Ninject, tuttavia, restituisce valori a un livello di astrazione più alto del necessario.
Ci sono due metodi che posso vedere per risolvere questo problema - A) in qualche modo rendere Ninject intercetta la classe specifica invece della sua interfaccia, e B) aggiunge un campo astratto a CommandBase
da usare per capire cosa è cosa. Non sono sicuro di come fare A, o anche se può essere fatto - almeno, non ho avuto successo con esso. B, d'altra parte, sembra essere 1) aggiungere informazioni ridondanti (il tipo già fornisce questo valore - quando non usiamo l'intercettazione, cioè), e 2) aggiungendo un altro possibile posto per farlo rompere. Quali sono i tuoi consigli per questo?