AOP, Unity, перехват метода

#c# #unity-container #aop

#c# #unity-контейнер #aop

Вопрос:

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

Возможно, я неправильно понимаю, как правильно это использовать, поскольку существует множество устаревшей и неполной информации без хороших рабочих примеров.

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

 
    public interface IApoClass
    {
        [LoggingCallHandler]
        void SomeAbstractAopMethod(string abstractparam);
        [LoggingCallHandlerAttribute]
        void SomeVirtualAopMethod(string virtualparam);
    }
    public abstract class AbstractAopClass : IApoClass
    {
        public abstract void SomeAbstractAopMethod(string whatthe);
        public virtual void SomeVirtualAopMethod(string abstractparam)
        {
            //essentiall do nothing
            return;
        }
    }
    public class NonAbstractAopMethod : AbstractAopClass
    {
        public override void SomeAbstractAopMethod(string whatthe)
        {
            Console.Write("I am the only enforced method");
        }
    }  

Контейнер:

             container.AddNewExtension<Interception>();
        //container.Configure<Interception>().SetInterceptorFor<IFrameworkInterceptionTest>(new InterfaceInterceptor());
        container.Configure<Interception>().SetInterceptorFor<IApoClass>(new InterfaceInterceptor());
  

Вызывающий код:

         //resolve it despite it not having and definition, but we've wired the container for the interface implemented by the abstract parent class
        var nonabstractmethod = DependencyResolver.Current.GetService<NonAbstractAopMethod>();  
        nonabstractmethod.SomeAbstractAopMethod("doubt this works");
        nonabstractmethod.SomeVirtualAopMethod("if the above didn't then why try");
  

Комментарии:

1. Кстати, я полагаю, что один из способов добиться этого — начать дооснащать классы типа уровня плохих сервисов интерфейсами, которые неизбежно значительно изменятся в дальнейшем. Оправдан ли плохой дизайн или это приведет к еще большим проблемам?

Ответ №1:

Ваше предположение верно: если вы хотите использовать перехват, вам нужно разрешить объект через контейнер, чтобы Unity мог создать прокси-объект или вернуть производный тип.

Методы перехвата Unity хорошо объясняют, как это работает.

Если я вас правильно понял, вы хотите выполнить перехват методов интерфейса, минимизируя изменения в существующей системе.

Вы должны быть в состоянии подключить перехват. Сначала зарегистрируйте интерфейс и конкретный тип, который вы хотите сопоставить, а затем установите перехват:

 IUnityContainer container = new UnityContainer();

container.AddNewExtension<Interception>();

container.RegisterType<IApoClass, NonAbstractAopMethod>()
            .Configure<Interception>()
            .SetInterceptorFor<IApoClass>(new InterfaceInterceptor());

DependencyResolver.SetResolver(new UnityServiceLocator(container));

var nonabstractmethod = DependencyResolver.Current.GetService<IApoClass>();
nonabstractmethod.SomeAbstractAopMethod("doubt this works");
nonabstractmethod.SomeVirtualAopMethod("if the above didn't then why try");
  

Если вам нужно сопоставить интерфейс с несколькими конкретными типами, вы можете сделать это, используя имя:

 container.RegisterType<IApoClass, NonAbstractAopMethod2>(
        typeof(NonAbstractAopMethod2).Name)
    .Configure<Interception>()
    .SetInterceptorFor<IApoClass>(
        typeof(NonAbstractAopMethod2).Name, 
        new InterfaceInterceptor()
);