Я начинаю с Castle DynamicProxy, и у меня есть этот пример для отслеживания изменений свойств объекта.
Вопросы:
- Должен ли я кэшировать (в статическом поле) экземпляр ProxyGenerator (), который я использую в AsTrackable ()? Я собираюсь использовать в веб-приложении ASP.NET, и я не был уверен, является ли класс потокобезопасным? Это дорого создавать?
- Если я оставлю код как есть, будут ли сгенерированные типы прокси повторно использоваться различными экземплярами ProxyGenerator. Я прочитал учебник кэширования , но не уверен, что означает «область видимости модуля».
- Есть ли другой совет с точки зрения производительности по улучшению кода?
Код:
class Program
{
static void Main(string[] args)
{
var p = new Person { Name = "Jay" }.AsTrackable();
//here's changed properties list should be empty.
var changedProperties = p.GetChangedProperties();
p.Name = "May";
//here's changed properties list should have one item.
changedProperties = p.GetChangedProperties();
}
}
public static class Ext
{
public static T AsTrackable<T>(this T instance) where T : class
{
return new ProxyGenerator().CreateClassProxyWithTarget
(
instance,
new PropertyChangeTrackingInterceptor()
);
}
public static HashSet<string> GetChangedProperties<T>(this T instance)
where T : class
{
var proxy = instance as IProxyTargetAccessor;
if (proxy != null)
{
var interceptor = proxy.GetInterceptors()
.Select(i => i as IChangedProperties)
.First();
if (interceptor != null)
{
return interceptor.Properties;
}
}
return new HashSet<string>();
}
}
interface IChangedProperties
{
HashSet<string> Properties { get; }
}
public class PropertyChangeTrackingInterceptor : IInterceptor, IChangedProperties
{
public void Intercept(IInvocation invocation)
{
invocation.Proceed();
this.Properties.Add(invocation.Method.Name);
}
private HashSet<string> properties = new HashSet<string>();
public HashSet<string> Properties
{
get { return this.properties; }
private set { this.properties = value; }
}
}
public class Person
{
public virtual string Name { get; set; }
public virtual int Age { get; set; }
}
}