如何在C#中自动生成Decorator模式

发布于 2024-10-06 13:39:46 字数 570 浏览 3 评论 0原文

我有一些接口,以及一个实现该接口的类,比如说:

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 扩展名的文本文件之外,还有更简单的方法来自动生成此类吗?

I have some interface, and a class implementing this interface, say:

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

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

Now, I want to create a class that decorates each of the concrete class methods with some specific logic, to be executed in non production environment, before and after the call.

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

My question is there a simpler way to auto generate such class other than use reflection on the interface and create a text file with cs extension?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

[浮城] 2024-10-13 13:39:46

就我个人而言,我只会在需要的地方明确记录,但如果您设置使用装饰器来执行此操作,则可以使用 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);

        }

    }
}

Personally I would just explicitly log where needed, but if you are set on using a decorator to do this you could use the RealProxy class.

It could look something like this:

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

        }

    }
}
噩梦成真你也成魔 2024-10-13 13:39:46

您尝试过 PostSharp 吗?它可以帮助您自动“检测”类并实现日志记录场景,而无需实际创建装饰器。

Have you tried PostSharp? It can help you automatically "instrument" classes and achieve your logging scenario without actually creating decorators.

闻呓 2024-10-13 13:39:46

What about the Logging Application block?

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

眉目亦如画i 2024-10-13 13:39:46

我编写了一个 T4 模板,能够根据一些简单的约定为相当复杂的类生成装饰器。该项目可以在 GitHub 上找到 - T4Decorators。与 T4MVC 类似,这就是我的想法。

I have written a T4 template capable of generating decorator for fairly complex classes based on some simple conventions. The project can be found on GitHub - T4Decorators. Works similar to T4MVC, that is where I got the idea.

公布 2024-10-13 13:39:46

你能用T4和反射吗?

也许这些其他问题可能会有所帮助:

Could you use T4 and reflection?

Maybe these other questions could help:

你是年少的欢喜 2024-10-13 13:39:46

我们有同样的要求,并编写了一个 Roslyn 生成器来执行此操作,请看这里: https://github.com/ proactima/ProxyGen
您需要稍微修改代码以满足您的需求。基本上,我们将接口的方法(全部来自某个命名空间)包装在“ReliableServiceCall”方法中。修改它来做其他事情是很简单的。

We have the same requirement and wrote a Roslyn generator to do this, take a look here: https://github.com/proactima/ProxyGen
You need to modify the code slightly to fit your needs. Basically we wrap the methods of an interface (all from a certain namespace) in a 'ReliableServiceCall' method. It's trivial to modify this to do something else.

硪扪都還晓 2024-10-13 13:39:46

这里最好的方法是通过接口使用装饰器模式。我知道这是一篇非常老的文章,但是如果您使用 IoC 注入器,例如 SimpleInjector,您可以用 1 行代码设置这些装饰器调用。然后你可以做这样的事情:

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

Best approach here is to use Decorator Pattern via interfaces. I know this is a very old post, but if you use an IoC injector, like SimpleInjector, you can setup these decorator calls in 1 line of code. Then you can do something like this:

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(); }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文