使用编译时编织的依赖注入?

时间:2014-05-11 09:16:32

标签: c# .net dependency-injection postsharp

我只是想了解PostSharp,说实话,我认为这很棒。

但有一件事我很难在PostSharp方面如何进行纯依赖注入(不是服务定位器)cannot be done,也许是因为编译时编织的结果。

来自PHP背景,Symfony有JMSAopBundle仍然允许依赖注入它的拦截器。

.Net是否有一些具有相同功能的库?

或者我错过了PostSharp的内容?

1 个答案:

答案 0 :(得分:16)

我不认为你在这里遗漏任何东西,这种限制确实是使用编译时编织的结果。

虽然我认为编译时编织工具在软件开发中占有一席之地,但我觉得它们经常被过度使用。我经常看到它们被用来修补应用程序设计中的缺陷。在我构建的应用程序中,我将通用接口应用于某些架构概念。例如,我定义:

  • 用于实现特定用例的服务的ICommandHandler<TCommand>接口;
  • 用于执行查询的服务的IQueryHandler<TQuery, TResult>接口;
  • 一个IRepository<TEntity>接口作为存储库的抽象;
  • 用于执行消息验证的组件的IValidator<TCommand>接口;
  • 依此类推,等等。

这允许我为这样的工件组创建一个通用装饰器(例如允许在自己的事务中运行每个用例的TransactionCommandHandlerDecorator<TCommand>)。装饰器的使用具有许多优点,例如:

  • 这些通用装饰器完全与工具无关,因为没有对代码编织工具或拦截库的引用。 PostSharp方面完全依赖于PostSharp,拦截器总是依赖于拦截框架,例如Castle.DynamicProxy。
  • 因为装饰器只是一个普通组件,所以可以将依赖关系注入到构造函数中,并且在使用依赖注入组合对象图时它们可以起到正常作用。
  • 装饰器代码非常干净,因为缺少与任何第三方工具的依赖。
  • 因为他们不再使用工具并允许依赖注入,所以装饰器可以轻松进行单元测试,而不必回复特殊技巧。
  • 需要应用横切关注点的应用程序代码也可以单独进行测试,因为装饰器不是在编译时编织的。在编译时编译装饰器时,您总是被迫执行应用程序代码测试的集成方式,或者需要恢复特殊构建技巧以防止它们应用于您的单元测试项目。
  • 装饰器可以在运行时动态和有条件地应用,因为没有编译时间代码编织。
  • 与代码编织相比,性能相同(甚至更快),因为在对象构建过程中没有反射。
  • 没有必要使用属性标记组件,以指出必须应用某些方面。这可以使您的应用程序代码不受任何关于这种交叉问题的了解,并且可以更容易地替换它。

关于这种应用程序设计已经写了很多;这里有一些我自己写的文章:

更新

  

装饰者很棒,但我喜欢AOP的是它的概念   建议和加入点。有没有办法模拟相同的功能   与装饰?我现在只能想到反思。

加入点是一个定义良好的位置,其中将关注一个问题&#34;。当您使用装饰师申请AOP时,您将受到限制。连接方法边界上的点。但是,如果您遵守SRPOCPISP,那么您将拥有非常精简的界面(通常使用单一方法)。这样做时,您会注意到几乎没有理由在您班级的任何其他地方设置加入点。

建议是一个&#34;关注点,可能会改变目标方法的输入和/或输出&#34;。当使用装饰器和基于消息的设计(我在这里宣传的东西)时,您的建议需要更改消息(或用更改的值替换完整的消息)或更改输出值。事情与代码编织没有什么不同 - 如果你申请建议,那么在建议申请的所有代码之间必须有一些共同点。