.NET下的AOP: PostSharp 原理分析

这段时间又在研究AOP了,对各种动态注入原理的AOP已经不感兴趣了,想研究一下静态注入的AOP,首当其冲的是PostSharp。

PS:Routing 和ASP.NET MVC的文章暂时放一放了

所谓静态注入,指的是在编译好的程序集(最好叫装配集)中的类型或者某个方法里注入IL代码(而不是在程序集的运行时注入),注入的地方称为"Join-Point".

有好多工具都可以读写程序集,注入IL代码,如Reflector的一个插件。但是PostSharp是在你编译一个程序集的时候就把IL注入到程序集里去了。

PostSharp并不像ReSharp一样,它不是VS的一个插件,它也不是在编辑器里修改代码的。

那么,PostSharp是如何起作用的呢?

它是怎么把自己插入到编译器的编译生成过程的呢?

我们都知道VS是通过MSBiuld来执行生成过程的,所以其实PostSharp是把自己作为一系列的Build Task来插入到生成过程的。

然后它修改了VS调用MSBiuld的默认配置。从而使VS的Build命令执行了它所指定的Task。下面的图说明了PostSharp的原理:

.NET下的AOP: PostSharp 原理分析

但是要真正理解静态注入的原理,要理解IL读写,还需要深入了解.net程序集,了解CLI和IL。

要真正知道PostSharp是如何工作的就必须了解MSBuild,知道怎么执行自定义的Build Task.

有很多东西VS都给我们做了,所以我们不了解,有很多开发人员现在还认为.NET 的程序集就是一个托管DLL文件呢!

接下来我将要写一些关于这方面的文章。

不过大家可以在下面的两个链接找到MSBuild的文档:

http://msdn.microsoft.com/zh-cn/library/wea2sca5.aspx

http://msdn.microsoft.com/zh-cn/library/0k6kkbsd.aspx

引用一下PostSharp文档里的一段:

 

Difference between the PostSharp Code Object Model and System.Reflection

PostSharp uses the entities defined in the specifications of the Common Language Infrastructure (CLI). However, developers are more familiar with the concepts of System.Reflection. They should be aware than System.Reflection includes great simplifications with respect to CLI specifications. CLI is module oriented. A module is an atomic artifact that can bind to other modules to form complete applications. In order to refer to types defined outside the current module, one uses references. By contrast, System.Reflection lives in the application universe where all references between modules are already resolved. In CLI and in PostSharp, references are explicitly represented as separate entities. But in System.Reflection, there is simply no concept of reference.

Modules

Modules (ModuleDeclaration) are atomic artifacts (i.e. they cannot be separated in smaller units). .NET modules are in fact Portable Executables (PE) just like native libraries and executables.

Assemblies

There is a common confusion about assemblies. An assembly, as indicated by its name, is a set of assembled modules and other files. So an assembly can be composed of many modules and even of unmanaged modules! It is a common mistake and misleading to consider that an assembly is composed of a single file.

What defines intrinsically the assembly is its assembly manifest (AssemblyManifestDeclaration). The manifest is composed of a list of references to modules and external assemblies, and of a list of exported types. The assembly manifest is contained in 'principal' managed module of the assembly (and not in a separate XML file, as claims another frequent mistake).

So the assembly manifest (AssemblyManifestDeclaration) is contained in a module (ModuleDeclaration); it contains references to external modules (ModuleRefDeclaration) and external assemblies (AssemblyRefDeclaration).

So let's summarize:

  • Modules, not assemblies, are the real atoms.
  • Assemblies are composed of many modules (managed or unmanaged executables).
  • Assemblies are defined by an assembly manifest.
  • The assembly manifest is stored in a managed module.
  • A managed module may, but is not required to, contain an assembly manifest.

PostSharp makes a difference between an assembly and an assembly manifest. The AssemblyEnvelope class encapsulates the assembly understood as a collection of modules. The AssemblyManifestDeclaration class encapsulates the manifest; it does not contain modules but is contained by a module. Where AssemblyManifestDeclaration contains a collection of references to modules, AssemblyEnvelope contain modules in themselves.

Domains

PostSharp domains (Domain) are similar to the .NET class AppDomain. Domains are contexts in which references between assemblies are solved. Just as in .NET, PostSharp assemblies are always loaded in a domain. PostSharp allows many domains to be loaded paralelly, even in the same AppDomain.

The base of the object tree is the ModuleDeclaration type. Since PostSharp is module-oriented, everything is contained in the module even the assembly manifest.

你可能感兴趣的:(.net)