2009-12-01 2 views
4

Итак, у меня есть эта проблема, и никто, кажется, не в состоянии помочь. Поэтому, вместо того, чтобы продолжать биться, я собираюсь выбросить его там, чтобы альтернативные способы обмануть этого конкретного кота.Атрибут перехвата AOP

я в настоящее время следующие:

public interface ICustomerService 
{ 
    Customer GetCustomer(int id); 
} 

public class CustomerService : ICustomerService 
{ 
    public Customer GetCustomer(int id) 
    { 
     ... 
    } 
} 

... и с Unity я имею установку МОК, и в то же время настройки перехвата, как:

IUnityContainer ioc = new UnityContainer(); 
ioc.RegisterType<ICustomerService, CustomerService>() 
    .Configure<Interception>() 
    .SetInterceptorFor<ICustomerService>(new InterfaceInterceptor()); 

Что я хочу для того чтобы достигнуть является чтобы иметь возможность размещать атрибуты в интерфейсе следующим образом:

public interface ICustomerService 
{ 
    [Log] 
    Customer GetCustomer(int id); 
} 

... определено как:

public class LogAttribute: HandlerAttribute 
{ 
    public override ICallHandler CreateHandler(IUnityContainer container) 
    { 
     return new LogHandler(); 
    } 
} 

..., а затем в классе LogHandler делать все протоколирование, что я хочу люблю:

public class LogHandler : ICallHandler 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) 
    { 
     ... log stuff 
    } 
} 

Что я хочу достичь, это система трассировки/регистрации, где журналы хендлер, что пространство имен. class.methodname вызывается, и родительское имя namespace.class.methodname, которое вызвало это. Я попытался без успеха использовать параметр «input» IMethodInvocation, чтобы получить информацию, которую я хочу, проблема заключается в том, что вход возвращает интерфейс «ICustomerService», в то время как проверка стекового кадра для родителя возвращает реализованный класс родителя (например, CustomerService), что означает, что при попытке создать древовидную структуру с использованием namespace.class.methodname в качестве идентификаторов сущностей идентификаторы и родительский идентификатор не совпадают.

Отбрасывание параметра в атрибут [Журнал] не будет работать ни на самом деле, потому что что я могу там положить? Если я поместил имя интерфейса, у меня все еще будет такая же проблема, как указано выше, где идентификатор одного - это интерфейс, а родительский - это класс реализации. И, я не могу поместить имя класса реализации в атрибут интерфейса, поскольку это побеждает цель иметь интерфейс в первую очередь!

Итак, это дилемма. Кто-нибудь получил свежие идеи?

ответ

1

В результате я использовал PostSharp для того, чтобы выполнить регистрацию точно так же. http://www.postsharp.org

+0

Да я в курсе PostSharp, но прежде, чем я начну усложняя вопрос далее с большим количеством ссылок и инструментов dll, стоит PostSharp, и что более важно, это то, что я хочу использовать, используя только Unity и Entlib? – krisg

+1

Я не знаю, возможно ли это с помощью Unity и Entlib. Я обнаружил, что PostSharp очень прост в использовании для этого, и поскольку это модификация IL времени компиляции, нет необходимости распространять сборки PostSharp. – user207462

1

У меня есть работа с использованием Unity и Interception. Из-за моей ужасной нехватки навыков настройки конфигурации мне пришлось делать это программно. Вам нужно настроить хотя бы один перехватчик, а также один или несколько объектов политики. О да, UnityContainer.Configure<Interception> имеет решающее значение.

Вроде как это:

// I'm using the TransparentProxyInterceptor because I want to trace EVERYTHING... 
var intp = myUnityContainer.Configure<Interception>(). 
    SetInterceptorFor(typeof(MyTypeToLog), new TransparentProxyInterceptor()); 

var policy = intp.AddPolicy("somePolicyName"); 

policy.AddMatchingRule<TypeMatchingRule>(
    new InjectionConstructor(
     new InjectionParameter(typeof(MyTypeToLog))) 
      .AddCallHandler(typeof(MyCallHandler), 
       new ContainerControlledLifetimeManager()); 

Конечно, мне нужно определить обработчик вызова перехвата, а также:

public class MyCallHandler : ICallHandler, IDisposable 
{ 
    public IMethodReturn Invoke(IMethodInvocation input, 
     GetNextHandlerDelegate getNext) 
    { 
     var methodReturn = getNext().Invoke(input, getNext); 

     // log everything... 
     LogMethodCall(input, methodReturn); 

     // log exception if there is one... 
     if (methodReturn.Exception != null) 
     { 
      LogException(methodReturn); 
     } 

     return methodReturn; 
    } 
} 
Смежные вопросы