Penso che tu sia equivoco che cosa accade. L'oggetto Foo
viene sostituito con un decoratore che contiene l'intercettore. Ecco un esempio semplicistico:
public class FooDecorator : Foo
{
private readonly Foo decorated;
public FooDecorator(Foo foo) { this.decorated = foo; }
public void ThrowsAnError(object param1, int param2)
{
// calls the decorated instance with supplied parameters
this.decorated.ThrowsAnError(param1, param2);
}
}
In altre parole, sarà trasferita i parametri che vengono forniti quando il Foo risolto è chiamata, l'istanza decorato.
Con l'intercettazione, tuttavia, tutto questo è un po 'più indiretto (e più lento), ma il concetto è lo stesso. Devo ammettere che non ho familiarità con l'intercettazione di Ninject, ma probabilmente c'è un metodo Proceed
sull'oggetto invocation
. In altre parole, si dovrebbe fare qualcosa di simile:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(),
invocation =>
{
try
{
// calls the decorated instance with supplied parameters
invocation.Proceed();
}
catch (Exception ex)
{
Kernel.Get<ILogger>().Log(ex);
}
});
UPDATE
Suppongo che il primo argomento del metodo InterceptReplace<T>
non è un delegato, ma un albero di espressione, come ad esempio Expression<Action<T>>
. Questo metodo, infatti, non viene chiamato, ma viene analizzato per scoprire quale metodo intercettare. In altre parole, poiché il metodo non viene mai chiamato, puoi semplicemente fornire qualsiasi argomento tu quale. Il trucco è lasciare che il compilatore C# sappia quale metodo utilizzare (se esiste). Non importa se fornisci spazzatura. Quando entrambi gli argomenti sono tipi di riferimento, questo sarà probabilmente funziona:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null),
vedo dove si sono provenienti da, ma penso che il PO avrà un problema di legame a tale metodo come il 'Kernel.InterceptReplace (foo => foo.ThrowsAnError(), ...); 'richiederebbe l'inserimento di argomenti, altrimenti non verrà compilato come ThrowsAnError richiede N argomenti a destra, nella tua istanza dovresti associarlo così * penso *. 'Kernel.InterceptReplace (foo => foo.ThrowsAnError (somehowSatisfyParam1, somehowSatisfyParam2), ...);' Tuttavia, potrei sbagliarmi. –
Grofit
Grofit è corretto, il 'foo.ThrowsAnError()' si aspetta comunque che i parametri siano stipulati –
@MarkWalsh: Ahh, capisco. Vedi il mio aggiornamento. – Steven