我正在开发一个项目,我们在AssemblyInfo.cs中有几个属性,这些属性被多播到特定类的方法。
[assembly: Repeatable(
AspectPriority = 2,
AttributeTargetAssemblies = "MyNamespace",
AttributeTargetTypes = "MyNamespace.MyClass",
AttributeTargetMemberAttributes = MulticastAttributes.Public,
AttributeTargetMembers = "*Impl", Prefix = "Cls")]
我不喜欢这个,是它将一条逻辑放入AssemblyInfo(信息,请注意!),这对于初学者来说根本不应该包含任何逻辑。最糟糕的部分是,实际的MyClass.cs在文件中没有任何属性,并且完全不清楚这个类的方法可能有它们。从我的角度来看,它极大地损害了代码的可读性(更不用说过度使用PostSharp会使调试成为一场噩梦)。特别是当你有多个组播属性时。
这里的最佳做法是什么?有没有人使用像这样的PostSharp属性?
答案 0 :(得分:12)
让我首先回答Max:事实上,方面不是替代到良好的OOP模式。它们是补充。任何良好的AOP设计都从良好的OOP设计开始。但OOP模式有时会迫使您手动编写大量管道代码。对于这些情况,方面可用于自动化 OOP模式的实现,不来替换它们。
当您智能地使用AOP时,您的解决方案可以变得更容易理解(业务代码不与维护代码混合),进行测试(您可以独立于业务代码测试方面,即您不必测试任何方面正确的业务方法跟踪),更改(您只需要在更改模式时更改方面,而不是更改模式的每个实现)。现在,如果您滥用AOP,如果您将其用作黑客工具,如果您之前没有考虑过OOP模式,那么您将获得的成本高于AOP的成本。作为任何敏锐的工具,应该智能地使用AOP。
回到原来的问题。
谁告诉你应该在AssemblyInfo.cs中放置方面?您可以创建一个名为GlobalAspects.cs的新文件,并将所有程序集级别的方面放在那里。你是对的,AssemblyInfo.cs应该只用于汇编级元数据。
但是和你一样,我不喜欢汇编级方面。我认为应该避免。组装级方面的主要问题是它们依赖于命名约定,这是邪恶的。 (这个邪恶在学术AOSD社区中被称为切入点脆弱。)的确,当你重命名一个类或命名空间时,你改变了方面适用的方法集,这很快就会成为一场噩梦。这就是我从不使用基于命名约定的方面的原因。
代码可读性怎么样?在很大程度上,我认为可读代码是短代码。如果我有一个名为CreateProduct的业务方法,我可能只想看到创建产品的代码。大多数时候,我对处理事务,异常或跟踪的代码不感兴趣。如果我知道某些方面可以解决这个问题就足够了。
我怎么知道?使用PostSharp,您可以使用Visual Studio扩展。使用AspectJ,您可以使用Eclipse的AspectJ插件(AJDT)。它们在IDE内部向您显示哪些方面应用于您当前看到的代码。如果你真的想看到细节(但你很少真的想要),你可以使用调试器进入方面,或使用Reflector查看生成的代码。
要点:
答案 1 :(得分:0)
我确信这将是一个不受欢迎的答案,但也许我可以获得同伴压力徽章......
你的直觉是正确的。将逻辑置于任何类型的元数据中都是一种可怕的,可怕的罪,一个人在不可维护的地狱火中永远燃烧。
我的意思是没有不尊重,虽然我确信它会被解释。
最佳做法是不使用“纵横面编程”工具,这些工具是拐杖,可以挽回糟糕的设计和测试实践。相反,看看你的设计并问自己“为什么。”
为什么我觉得有必要使用它 工具?我有什么设计问题 试图解决?
一旦掌握了问题,请选择设计模式解释(Shalloway& Trott)或 Head First Design Patterns (Freeman,Robson,Bates ,& Sierra)。
最后,面向模式的解决方案将更容易理解,更容易测试,更容易更改。唯一的额外费用是掌握设计模式的一次性费用,而不是试图找出所有这些方面的位置,它们如何组合在一起以及每次进行更改时它们如何相互影响的经常性费用。