Postsharp 3rd方组件事件拦截

发布于 2024-11-30 22:37:40 字数 719 浏览 3 评论 0 原文

我有一个关于使用 C# 和 Postsharp 进行事件拦截的问题。

我想在 postsharp 中取消执行像 BeforeDropDown、RowSelected MouseClick 和 EventInterceptionAspect 这样的事件。

但我找不到可以编写代码的合适地方。 示例:

我尝试了这样的事情:

[Serializable]
class EventInter : EventInterceptionAspect
{
    public override bool CompileTimeValidate(System.Reflection.EventInfo targetEvent)
    {
        return "FormClosed".Equals(targetEvent.Name);
    }

    public override void OnInvokeHandler(EventInterceptionArgs args)
    {
        if condition executes method otherwise no
    }
}

形式为:

[EventInter]
public partial class Frm_RomperMesa : KryptonForm

但它不起作用。所以我想知道是否有可能实现我想要的。

提前致谢。我希望说清楚。

I have a question about events interception with c# and Postsharp.

I would like to cancel the execution of events like BeforeDropDown, RowSelected MouseClick with EventInterceptionAspect in postsharp.

But i can not find a proper place where i can write the code.
example:

i tried something like this:

[Serializable]
class EventInter : EventInterceptionAspect
{
    public override bool CompileTimeValidate(System.Reflection.EventInfo targetEvent)
    {
        return "FormClosed".Equals(targetEvent.Name);
    }

    public override void OnInvokeHandler(EventInterceptionArgs args)
    {
        if condition executes method otherwise no
    }
}

in the form:

[EventInter]
public partial class Frm_RomperMesa : KryptonForm

But it didn´t work. So i want to know if it is possible to achieve what i want.

Thanks in advace. I hope be clear.

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

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

发布评论

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

评论(2

谜泪 2024-12-07 22:37:40

是的,这是可能的。问题是,您试图将事件拦截方面应用于另一个程序集中定义的事件,而您无法在代码中执行此操作。您甚至无法覆盖该事件,因为它设置为使用后面的设计器代码中的基本表单类型进行处理,

this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);

您必须修改程序集才能执行此操作。使用以下方面和链接修改您的

public class EventAspectProvider : TypeLevelAspect , IAspectProvider
    {
        public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
        {
            Type t = (Type)targetElement;

            EventInfo e = t.GetEvents().First(c => c.Name.Equals("FormClosing"));

            return new List<AspectInstance>() { new AspectInstance(e, new EventInter()) };
        }

    }

    [Serializable]
    public class EventInter : EventInterceptionAspect
    {

        public override void OnInvokeHandler(EventInterceptionArgs args)
        {
            int x = 0;

            if (x > 0) //Do you logic here
            {
                args.ProceedInvokeHandler();
            }
        }
    }

基本上可以归结为修改 System.Windows.Forms.dll 我不推荐。但如果是其他第三方供应商库,那就去吧。

yes, it is possible. The problem is, you're trying to apply an event interception aspect to an event defined in another assembly which you can't do within your code. You can't even override the event because it's setup to be handled using the base Form type in the designer code behind

this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);

you will have to modify the assembly to do this. Use the following aspect and the links to modify your

public class EventAspectProvider : TypeLevelAspect , IAspectProvider
    {
        public IEnumerable<AspectInstance> ProvideAspects(object targetElement)
        {
            Type t = (Type)targetElement;

            EventInfo e = t.GetEvents().First(c => c.Name.Equals("FormClosing"));

            return new List<AspectInstance>() { new AspectInstance(e, new EventInter()) };
        }

    }

    [Serializable]
    public class EventInter : EventInterceptionAspect
    {

        public override void OnInvokeHandler(EventInterceptionArgs args)
        {
            int x = 0;

            if (x > 0) //Do you logic here
            {
                args.ProceedInvokeHandler();
            }
        }
    }

Basically it boils down to modifying the System.Windows.Forms.dll which I don't recommend. But if it's some other 3rd party vendor library, then go for it.

指尖上的星空 2024-12-07 22:37:40

解决方法是反其道而行之:在挂钩到事件的方法上使用方面,并在满足条件时取消该方法的正常执行。这不会阻止引发事件表单,但会阻止执行事件处理代码。

[EventInter]
private void someForm_FormClosed(object sender, EventArg arg) {}

我们在项目中经常使用这种方法。我们有几个方面适用于事件处理方法(异常处理、游标处理等)。

我们更进一步,我们在程序集级别应用这些方面,并使用 CompileTimeValide 来识别事件处理方法的签名。从理论上讲,它并不是100%可靠,但到目前为止我们还没有发现这种方法有任何问题。

A workaround is to do it the other way around: Use an aspect on the method that is hooked to the event and cancel the normal execution of the method if the condition is met. This does not prevent the event form being raised but it prevents your event handling code from being executed.

[EventInter]
private void someForm_FormClosed(object sender, EventArg arg) {}

We use this approach a lot in our project. We have several aspects that apply to event handling methods (exception handling, cursors handling, etc...).

We go a little further, we apply the aspects at the assembly level and we use CompileTimeValide to recognize the signature of an event handling method. In theory, it's not 100% reliable, but we have not found any problems with this approach so far.

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