Myślę, że nieporozumienie, co się dzieje. Twój obiekt Foo
zostanie zastąpiony dekoratorem, który zawiera przechwytywacz. Oto uproszczony przykład:
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);
}
}
Innymi słowy, parametry, które są dostarczane, gdy rozwiązany Foo jest nazywany, zostanie przeniesiony na zdobionej instancji.
Jednak z przechwytywaniem wszystko to jest nieco bardziej pośrednie (i wolniejsze), ale koncepcja jest taka sama. Muszę przyznać, że nie jestem zaznajomiony z przechwytywaniem Ninject, ale prawdopodobnie istnieje metoda Proceed
na obiekcie . Innymi słowy, należy zrobić tak:
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
Zakładam, że pierwszy argument metody InterceptReplace<T>
nie jest delegatem, ale drzewa wyrażenie, takie jak Expression<Action<T>>
. Ta metoda w rzeczywistości nie jest wywoływana, ale jest analizowana, aby dowiedzieć się, która metoda przechwycić. Innymi słowy, ponieważ ta metoda nigdy nie jest wywoływana, możesz po prostu podać dowolny argument. Sztuczka polega na tym, aby kompilator C# wiedział, której metody należy przeciążać (jeśli jest). Nie ma znaczenia, czy dostarczasz śmieci. Kiedy oba argumenty są typy referencyjne, to prawdopodobnie będzie działać:
Kernel.InterceptReplace<Foo>(foo => foo.ThrowsAnError(null, null),
widzę gdzie pochodzą, ale myślę, że PO będzie miało wiążącą tej metody jako problemowi, 'Kernel.InterceptReplace (foo => foo.ThrowsAnError(), ...); 'wymagałoby wprowadzenia tam argumentów, w przeciwnym razie nie skompiluje się, ponieważ ThrowsAnError wymaga poprawnie N argumentów, w twojej instancji będziesz musiał powiązać, tak jak ja * myślę *. 'Kernel.InterceptReplace (foo => foo.ThrowsAnError (jakośSatisfyParam1, jakośSatisfyParam2), ...);' Mogę się mylić. –
Grofit
Grofit jest poprawny, '' foo.ThrowsAnError() 'nadal będzie oczekiwał zapisu paramusterów –
@MarkWalsh: Ahh, rozumiem. Zobacz moją aktualizację. – Steven