Как автоматически генерировать шаблон Decorator в C # - PullRequest
6 голосов
/ 08 декабря 2010

У меня есть некоторый интерфейс и класс, реализующий этот интерфейс, скажем:

interface IMyInterface
{
     void Func1();
     void Func2();
}

class Concrete : IMyInterface
{
     public virtual void Func1() { //do something }
     public virtual void Func2() { //do something }
}

Теперь я хочу создать класс, который украшает каждый из методов конкретного класса некоторой определенной логикой, которая будет выполнятьсяв непроизводственной среде, до и после звонка.

class Decorator : Concrete
{ 
     public override void Func1() { Pre(); base.Func1; Post(); }
     public override void Func2() { Pre(); base.Func2; Post(); }
}

У меня вопрос, есть ли более простой способ автоматически сгенерировать такой класс, кроме использования отражения в интерфейсе и создания текстового файла с расширением cs?

Ответы [ 7 ]

9 голосов
/ 08 декабря 2010

Лично я бы просто явно входил в систему, когда это необходимо, но если вы настроены на использование декоратора, вы можете использовать класс RealProxy .

Это может выглядеть примерно так:

public class DecoratorProxy<T> : RealProxy
{
    private T m_instance;

    public static T CreateDecorator<T>(T instance)
    {
        var proxy = new DecoratorProxy<T>(instance);
        (T)proxy.GetTransparentProxy();
    }

    private DecoratorProxy(T instance) : base(typeof(T))
    {
        m_instance = instance;

    }
    public override IMessage Invoke(IMessage msg)
    {
        IMethodCallMessage methodMessage = msg as IMethodCallMessage;
        if (methodMessage != null)
        {
            // log method information

            //call method
            methodMessage.MethodBase.Invoke(m_instance, methodMessage.Args);
            return new ReturnMessage(retval, etc,etc);

        }

    }
}
2 голосов
/ 07 октября 2014

Я написал шаблон T4, способный генерировать декоратор для довольно сложных классов на основе некоторых простых соглашений.Проект можно найти на GitHub - T4Decorators .Работает аналогично T4MVC, вот откуда у меня появилась идея.

2 голосов
/ 08 декабря 2010

А как насчет блока приложения регистрации?

http://msdn.microsoft.com/en-us/library/ff647183.aspx

2 голосов
/ 08 декабря 2010

Вы пробовали PostSharp ? Он может помочь вам автоматически «инструментировать» классы и достичь сценария регистрации без фактического создания декораторов.

1 голос
/ 19 февраля 2016

У нас такое же требование и мы написали генератор Roslyn для этого, посмотрите здесь: https://github.com/proactima/ProxyGen Вам нужно немного изменить код, чтобы он соответствовал вашим потребностям. По сути, мы заключаем методы интерфейса (все из определенного пространства имен) в метод ReliableServiceCall. Тривиально изменить это, чтобы сделать что-то еще.

1 голос
/ 08 декабря 2010

Не могли бы вы использовать Т4 и отражение?

Может быть, эти вопросы могут помочь:

0 голосов
/ 04 августа 2018

Лучшим подходом здесь является использование Pattern Decorator через интерфейсы. Я знаю, что это очень старая статья, но если вы используете IoC-инжектор, например SimpleInjector, вы можете настроить эти вызовы декоратора в одной строке кода. Тогда вы можете сделать что-то вроде этого:

public class Decorator : IMyInterface
{ 
     private readonly IMyInterface _next;

     public Decorator (IMyInterface next) { _next = next; }

     public override void Func1() { Pre(); _next.Func1; Post(); }
     public virtual void Func2() { Pre(); _next.Func2; Post(); }
}
...