What I want is create caching proxies for all my components decorated with some attributes. So, I made Autofac Module like this:
public class CachingModule : Autofac.Module
{
private readonly ProxyGenerator generator;
public CachingModule()
{
generator = new ProxyGenerator();
}
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
var type = registration.Activator.LimitType;
if (type.GetCustomAttribute<CachedAttribute>(true) != null
|| type.GetMethods().Any(m => m.GetCustomAttribute<CachedAttribute>(true) != null))
{
registration.Activating += (s, e) =>
{
var proxy = generator.CreateClassProxyWithTarget(e.Instance.GetType(),
e.Instance,
interceptors: e.Context.Resolve<IEnumerable<CacheInterceptor>>().ToArray());
e.ReplaceInstance(proxy);
};
}
}
}
What I can't get to work is: I can't create proxy instances with parametrized constructors, is there any way to do this?
Ok, I've managed to get it all working, so for anyone interested here is a sample of proxy generation with non-default constructors
public class CachingModule : Autofac.Module
{
private readonly ProxyGenerator generator;
public CachingModule()
{
generator = new ProxyGenerator();
}
protected override void AttachToComponentRegistration(IComponentRegistry componentRegistry, IComponentRegistration registration)
{
var type = registration.Activator.LimitType;
if (type.GetCustomAttribute<CachedAttribute>(true) != null
|| type.GetMethods().Any(m => m.GetCustomAttribute<CachedAttribute>(true) != null))
{
var ctors = type.GetConstructors();
registration.Activating += (s, e) =>
{
if (e.Instance is IProxyTargetAccessor)
{
return;
}
var param = new List<object>();
var infos = ctors.First().GetParameters();
if (ctors.Length > 0 && infos.Length > 0)
{
foreach (var p in e.Parameters)
{
foreach (var info in infos)
{
if (p.CanSupplyValue(info, e.Context, out var valueProvider))
{
param.Add(valueProvider());
}
}
}
}
var instance = e.Instance;
var toProxy = instance.GetType();
var proxyGenerationOptions = new ProxyGenerationOptions(new CacheProxyGenerationHook());
var proxy = generator.CreateClassProxyWithTarget(toProxy,
instance,
proxyGenerationOptions,
param.ToArray(),
interceptors: e.Context.Resolve<IEnumerable<CacheInterceptor>>().ToArray());
e.ReplaceInstance(proxy);
};
}
}
}