事件订阅最佳实践

时间:2015-01-21 09:25:26

标签: c# events frameworks

我最近在我们的申请中偶然发现了以下内容,我很想知道这是好事还是坏事。我看到的是在应用程序,业务逻辑以及最终我们的框架中不同级别上订阅的事件。

我们具有对用户进行身份验证和授权的功能,这是由HttpModule编排的,它基本上执行以下操作(我只包括最相关的部分):

    public class FooModule : IHttpModule
    {
        private IIdentityProvider _identityProvider;

        public void Init(HttpApplication context)
        {
            _identityProvider = TypeFactory.Create<IIdentityProvider>("...type string from configuration...");
            identityProvider.Init(context, ...);

            context.PostAuthenticateRequest += OnAuthenticateRequest;
            context.PostAuthenticateRequest += OnAuthenticateRequestLogging;
        }

        ...
    }

到目前为止,非常好:HttpModule识别配置的身份提供程序,初始化它并订阅某些事件。事件处理程序在这里没有问题,所以我省略了它们。

然后,在任意身份提供者的初始化中:

public class BarIdentityProvider : IIdentityProvider
{
    public void Init(HttpApplication httpApplication, ...)
    {
        var authorizer = new BarAuthorizationProvider();
        authorizer.Init(httpApplication, ...);

        httpApplication.PostAuthenticateRequest += httpApplication_PostAuthenticateRequest;
        httpApplication.AuthorizeRequest += httpApplication_AuthorizeRequest;
    }

    ...
}

在AuthorizationRequestHandler中会发生以下情况:

public class BarAuthorizationProvider
{
    public void Init(HttpApplication httpApplication, ...)
    {
        httpApplication.PostAuthorizeRequest += OnAuthorizeRequest;
    }

    ...
}

正如您所看到的,在FooModule,BarIdentityProvider和BarAuthorizationProvider中都有订阅的事件,对我而言,这些事件都是事件意大利面。此外,这样做:

var authorizer = new BarAuthorizationProvider();
authorizer.Init(httpApplication, ...);

我不希望authorizer订阅各种活动并且神奇地工作。

作为一名软件开发人员,我希望:

  1. 一个HttpModule,它订阅必要的事件并向身份提供者和授权提供者请求身份和访问信息。事件处理在提供程序中最小化。
  2. 多个HttpModule(即身份验证和授权模块),每个HttpModule都订阅必要的事件。事件处理在提供程序中最小化。
  3. 我是否正确或有反对我期望的论据?

1 个答案:

答案 0 :(得分:0)

我的第一个问题是,&#34;事件处理在提供商中最小化是很重要的&#34;?即特定的优势在于实现这一目标?

我也想知道&#34;事件意大利面&#34;应该是的意思。我的意思是,它清楚地引用了&#34; spaghetti code&#34;这个古老的概念,但是这个概念指的是执行路径复杂的代码,最常见的原因是使用了非结构化的流控制(即{ {1}}陈述)。我不知道在讨论事件处理时,有什么类似意大利面条的东西。

换句话说,短语&#34; event spaghetti&#34;这里似乎只是偏见。即字#&#34; spaghetti&#34;只是被抛入,因为它已被理解为贬义。但是对于实施缺乏明确的反对意见,贬义似乎没有道理,而且“#34; spaghetti&#34;似乎没有提供真正有用的比喻,因为它在&#34; spaghetti code&#34;。

的背景下。


所以,回到&#34;最小化提供商中的事件处理&#34;。为什么这很重要?你写的是#34;事件处理程序在这里没有问题&#34;,但这似乎表明提供程序中的处理程序是合适的。即他们的工作与提供者相关(可能仅 到提供者)。那他们还有什么办法呢?

在我看来(我写的这个事实表明你的问题可能被认为是偏离主题的,是#34;主要是基于意见的&#34;,但我认为这是一个客观的方式来看待在这个,即使这只是我的意见:)),基于事件的编程模型的一大优势是减少了耦合。假设必须在某处完成工作,订阅这些事件的这些提供者对象的替代方案是让其他对象了解提供者对象的需求,并在提供者对象上满足这种需求&# 39;代表。

但是,您只是载有具有提供者对象特定知识的其他对象。这增加了类型之间的耦合。这通常是的事情。


另一方面,如果您认为提供程序中的事件处理程序可以移动到其他类型而不会更强烈地耦合类型,那么这表明事件处理程序在提供程序中确实不合适。但在这种情况下,这些事件处理程序的特定细节在这里肯定是相关的,与你的断言相反。

即。事件处理程序的 where 取决于它的功能。但是,由于您似乎并不关心这些处理程序的具体内容,这表明它们属于它们所属的位置,因此订阅事件根本不是问题。