Как получить параметры конструктора компонента автозапуска при активации - PullRequest
0 голосов
/ 15 января 2019

Я хочу создать кеширующие прокси для всех моих компонентов, украшенных некоторыми атрибутами.Итак, я создал модуль Autofac следующим образом:

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);
            };
        }
    }
}

То, что я не могу заставить работать: я не могу создавать экземпляры прокси с параметризованными конструкторами, есть ли способ сделать это?

1 Ответ

0 голосов
/ 16 апреля 2019

Хорошо, мне удалось заставить все это работать, поэтому для всех, кто заинтересован, приведу пример генерации прокси с конструкторами не по умолчанию

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);
            };
        }
    }
}
...