Что ж, вы определенно не можете сделать это без изменения кода в любом классе (при условии, что вы также не хотите менять везде, где вызывается class1.Execute
) - по крайней мере, без некоторой глубокой магической обработки кода / инструментовки. Однако вы можете довольно легко добавить событие в Class1
:
public class Class1
{
// TODO: Think of a better name :)
public event EventHandler ExecuteCalled = delegate {};
public void Execute()
{
ExecuteCalled(this, EventArgs.Empty);
// Do your normal stuff
}
}
Бит delegate{}
предназначен только для того, чтобы убедиться, что всегда есть хотя бы зарегистрированный обработчик события no-op - это означает, что вам не нужно проверять на ничтожность.
Затем вы подключите его, написав:
Class1 class1 = new Class1();
Logger logger = new Logger();
class1.ExecuteCalled += (sender, args) => logger.Write(sender.ToString());
(Предполагается, что вы используете C # 3, поэтому вам доступны лямбда-выражения - дайте мне знать, если это не так.)
Если Class1
реализует интерфейс (скажем, IFoo
), вы можете написать реализацию интерфейса, которая оборачивает другую реализацию, и просто регистрировать перед каждым вызовом:
public sealed class LoggingFoo : IFoo
{
private readonly IFoo original;
private readonly IFoo logger;
public LoggingFoo(IFoo original, Logger logger)
{
// TODO: Check arguments for nullity
this.original = original;
this.logger = logger;
}
// Implement IFoo
public void Execute()
{
logger.Write("Calling Execute on {0}", original);
original.Execute();
}
}
Тогда просто используйте эту обертку вокруг «реальной» реализации везде, где вы в данный момент просто используете реализацию.