Перехват с структурой - PullRequest
4 голосов
/ 25 октября 2010

Я пытаюсь сделать некоторый перехват на основе атрибутов, используя Structuremap, но я пытаюсь связать последние свободные концы.

У меня есть собственный Реестр, который сканирует мои сборки, и в этом Реестре я определил следующий ITypeInterceptor, цель которого - сопоставить типы, украшенные данным атрибутом, а затем применить перехватчик, если он совпадает. Класс определяется так:

public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor> 
   : TypeInterceptor 
   where TAttribute : Attribute 
   where TInterceptor : IInterceptor
{
    private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator();

    public object Process(object target, IContext context)
    {
        return m_proxyGeneration.CreateInterfaceProxyWithTarget(target, ObjectFactory.GetInstance<TInterceptor>());
    }

    public bool MatchesType(Type type)
    {
        return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0;
    }
}

//Usage
[Transactional]
public class OrderProcessor : IOrderProcessor{
}
...   
public class MyRegistry : Registry{
    public MyRegistry()
    {
         RegisterInterceptor(
             new AttributeMatchTypeInterceptor<TransactionalAttribute, TransactionInterceptor>());
         ...
    }
}

Я использую DynamicProxy из Castle.Core для создания перехватчиков, но моя проблема в том, что объект, возвращенный из вызова CreateInterfaceProxyWithTarget (...) , не реализует интерфейс, который инициировал создание целевого экземпляра в структуре карты (т.е. IOrderProcessor в приведенном выше примере). Я надеялся, что параметр IContext откроет этот интерфейс, но я могу только удержать конкретный тип (т.е. OrderProcessor в приведенном выше примере).

Я ищу руководство о том, как заставить этот сценарий работать, либо вызывая ProxyGenerator для возврата экземпляра, который реализует все интерфейсы в качестве целевого экземпляра, либо получая запрошенный интерфейс из структуры структуры, либо через какой-либо другой механизм.

1 Ответ

2 голосов
/ 09 августа 2011

Я действительно получил кое-что работающее с небольшим предостережением, поэтому я просто опубликую это как ответ.Хитрость заключалась в том, чтобы получить интерфейс и передать его в CreateInterfaceProxyWithTarget .Моя единственная проблема состояла в том, что я не мог найти способ запросить IContext о том, какой интерфейс он в настоящее время разрешал, поэтому я просто нашел первый интерфейс на цели, который работал для меня.См. Код ниже

public class AttributeMatchTypeInterceptor<TAttribute, TInterceptor> : 
    TypeInterceptor
    where TAttribute : Attribute 
    where TInterceptor : IInterceptor
{
    private readonly ProxyGenerator m_proxyGeneration = new ProxyGenerator();

    public object Process(object target, IContext context)
    {
        //NOTE: can't query IContext for actual interface
        Type interfaceType = target.GetType().GetInterfaces().First(); 
        return m_proxyGeneration.CreateInterfaceProxyWithTarget(
            interfaceType, 
            target, 
            ObjectFactory.GetInstance<TInterceptor>());
    }

    public bool MatchesType(Type type)
    {
        return type.GetCustomAttributes(typeof (TAttribute), true).Length > 0;
    }
}

Надеюсь, это кому-нибудь поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...