Замок DynamicProxy2:Поместить цель внутрь Перехватчика?
-
05-07-2019 - |
Вопрос
Я использую Castle DynamicProxy2 для "привязки" интерфейсов для извлечения полей из словаря.Например, учитывая следующий класс:
public class DataContainer : IDataContainer
{
private Dictionary<string, object> _Fields = null;
public Dictionary<string, object> Data
{
get { return _Fields ?? (_Fields = new Dictionary<string, object>()); }
}
}
Я хочу использовать следующий интерфейс в качестве прокси-сервера интерфейса для извлечения значения "Name" из словаря полей:
public interface IContrivedExample
{
string Name { get; }
}
Из перехватчика я хочу получить "целевой" DataContainer и вернуть значение "Name":
public void Intercept(IInvocation invocation)
{
object fieldName = omitted; // get field name based on invocation information
DataContainer container = ???; // this is what I'm trying to figure out
invocation.ReturnValue = container.Fields[fieldName];
}
// Somewhere in code
var c = new DataContainer();
c.Fields.Add("Name", "Jordan");
var pg = new ProxyGenerator();
IContrivedExample ice = (IContrivedExample) pg.CreateInterfaceProxyWithTarget(..., c, ...);
Debug.Assert(ice.Name == "Jordan");
Есть какие-нибудь мысли о том, как получить основную цель
Примечание:это надуманный пример, который я использую, чтобы установить некоторый контекст вокруг возникшего у меня вопроса.
Решение
Я понял это. Вы должны привести Прокси к IProxyTargetAccessor:
public void Intercept(IInvocation invocation)
{
object fieldName = omitted; // get field name based on invocation information
var accessor = invocation.Proxy as IProxyTargetAccessor;
DataContainer container = (DataContainer) accessor.DynProxyGetTarget();
invocation.ReturnValue = container.Fields[fieldName];
}
Другие советы
К чему такие хлопоты?
использование
var container = invocation.InvocationTarget as DataContainer;
Кстати, IIUC, вы пытаетесь реализовать то, что уже предоставлено Адаптерный словарь замка.Почему бы не использовать то, что уже есть?