Вы можете сделать это во время выполнения, используя событие .NET AOP Framework, если это не является основной целью этого типа фреймворка.
Я активно работаю над новым, который может обрабатывать события, если ваш метод не виртуальный.
Вы можете ознакомиться с средой выполнения NConcern .NET AOP Framework.
Патч обезьяны "аспект":
public class MonkeyPatch : IAspect
{
static public void Patch(MethodInfo oldMethod, MethodInfo newMethod)
{
//update monkey patch dictionary
MonkeyPatch.m_Dictionary[oldMethod] = newMethod;
//release previous monkey patch for target method.
Aspect.Release<MonkeyPatch>(oldMethod);
//weave monkey patch for target method.
Aspect.Weave<MonkeyPatch>(oldMethod);
}
static private Dictionary<MethodInfo, MethodInfo> m_Dictionary = new Dictionary<MethodInfo, MethodInfo>();
public IEnumerable<IAdvice> Advise(MethodInfo method)
{
if (MonkeyPatch.m_Dictionary.ContainsKey(_Method))
{
yield return Advice(MonkeyPatch.m_Dictionary[_Method]);
}
}
}
Пластырь :
static public void main(string[] args)
{
//create Boo2, a dynamic method with Boo signature.
var boo2 = new DynamicMethod("Boo2", typeof(void), new Type[] { typeof(Foo) }, typeof(Foo), true);
var body = boo2.GetILGenerator();
//Fill your ILGenerator...
body.Emit(OpCodes.Ret);
//Apply the patch
MonkeyPatch.Patch(typeof(Foo).GetMethod("Boo"), boo2);
}
во-вторых, если вам просто нужно что-то вызвать после исходного вызова, вы находитесь в АОП-прицеле, и вы можете сделать это так...
Аспект наблюдения:
public class Observation : IAspect
{
static public void Observe(MethodInfo method, Action action)
{
//update observation dictionary
Observation.m_Dictionary[method] = action;
//release observation aspect for target method
Aspect.Release<Observation>(method);
//weave observation aspect for target method.
Aspect.Weave<Observation>(method);
}
static private Dictionary<MethodInfo, Action> m_Dictionary = new Dictionary<MethodInfo, Action>;
public IEnumerable<IAdvice> Advice(MethodInfo method)
{
if (Observation.m_Dictionary.ContainsKey(method))
{
yield return Advice.Basic.After(Observation.m_Dictionary[method]);
}
}
}
Вариант использования:
static public void main(string[] args)
{
Observation.Observe(typeof(Foo).GetMethod("Boo"), () => { /* paste here your notification code... */ });
}
person
Tony THONG
schedule
09.12.2016
protected virtual
? - person PMF   schedule 12.12.2013protected virtual
, однако я на самом деле ищу решение, которое позволит не трогать исходный код. - person Ryszard Dżegan   schedule 12.12.2013Foo
. Тест завершен, когдаBoo
завершен. Мне нужно поместить уведомление в методBoo
, чтобы остановить мой тест. - person Ryszard Dżegan   schedule 12.12.2013Boo
— это что-то вроде спагетти-кода. Внутри находитсяif
. Мой тест завершен в течение этогоif
. Я не хочу делать какой-либо рефакторинг этого метода. Просто сделайте его копию, найдите этотif
внутри этой копии и после этого прикрепите уведомление. Главное здесь — не изменять исходныеFoo
иBoo
. - person Ryszard Dżegan   schedule 12.12.2013Boo
, а вызывающий метод должен быть в разных классах, чтобы вы могли издеваться над бу как обычно. В качестве альтернативы создайте Boointernal protected virtual
(при условии, что для вашей тестовой сборки установлено значение InternalsVisibleTo) и создайте производный класс Foo2 в своем тесте, где вы можете переопределить Boo. - person PMF   schedule 12.12.2013