Динамический прокси-сервер Castle не перехватывает вызовы методов при вызове из класса
я столкнулся с немного (что я думаю) странным поведением при использовании динамического прокси-сервера замка.
следующий код:
class Program
{
static void Main(string[] args)
{
var c = new InterceptedClass();
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxyWithTarget(c, i);
cp.Method1();
cp.Method2();
Console.ReadLine();
}
}
public class Interceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine(string.Format("Intercepted call to: " + invocation.Method.Name));
invocation.Proceed();
}
}
public class InterceptedClass
{
public virtual void Method1()
{
Console.WriteLine("Called Method 1");
Method2();
}
public virtual void Method2()
{
Console.WriteLine("Called Method 2");
}
}
Я ожидал получить результат:
- перехваченный вызов: Method1
- Называется Метод 1
- перехваченный вызов: Method2
- Называется Метод 2
- перехваченный вызов: Method2
- Называется Метод 2
однако что я получил:
- перехваченный вызов: Method1
- Называется Метод 1
- Называется Метод 2
- перехваченный вызов: Method2
- Называется Метод 2
насколько я могу судить, динамический прокси-сервер может только вызывать прокси-метод, если вызов поступает извне самого класса, поскольку Method2 был перехвачен при вызове из программы, но не изнутри InterceptedClass.
Я могу понять, что при выполнении вызовов из проксированного класса он больше не будет проходить через прокси-сервер, но просто хотел проверить, что это ожидалось, и если это так, то посмотрите, есть ли все равно, чтобы перехватить все вызовы независимо от того, откуда они вызываются?
спасибо
1 ответов
EDIT: tl;dr - я только что попытался создать прокси-сервер по-другому, как описано ниже, и он производит вывод, который вы искали. Я просто должен был изменить это:
var c = new InterceptedClass();
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxyWithTarget(c, i);
для этого:
var i = new Interceptor();
var cp = new ProxyGenerator().CreateClassProxy<InterceptedClass>(i);
как я понимаю, прокси-генератор эффективно создает объект-оболочку. Это два отдельных объекта - один просто обертка вокруг другого, с перехватом и т. д. В слое обертки.
трудно понять, как это мог бы изменить то, что экземпляр InterceptedClass
сделал со своими вызовами метода:
- DynamicProxy не может изменить тип существующего объекта; после создания объекта его тип фиксируется
- DynamicProxy не может изменить способ привязки существующих вызовов к существующему объекту
если вы хотите Method1
называть Method2
via обертка с использованием текущего кода создания прокси-сервера, вам нужно будет сообщить существующий объект об оболочке, либо как поле внутри нее, либо как параметр метода.
кроме того, может быть другой способ создания прокси-сервера для начала - тот, где прокси is в некотором смысле целевой объект. Подозреваю, вы захотите взглянуть на CreateClassProxy
, а не CreateClassProxyWithTarget
- Я подозреваю, что это тот факт, что вы поставляет объект, который вызывает у вас проблемы.
является ли поведение, которое вы видите, "ожидаемым" или нет очевидно, зависит от ваших ожиданий - но это, безусловно, что я ожидал бы, не зная ничего о Castle Dynamic Proxy:)