IContextAttribute 是判断某一个System.Runtime.Remoting.Contexts.Context是否符合它的要求.如果任何一个IContextAttribute或其他对象认为不符合,则创建一个新的Context,然后进入这个Context,再调用所有的IContextAttribute.GetPropertiesForNewContext . 对于 事务/同步 等东西的NOTSUPPORT/SUPPORT/REQUIRED/REQUIRE_NEW就是在这个基础上实现的.
就如 IContextAttribute 一样,DotNet为消息的分发提供了扩展方法:
DotNet寻找一个类型上的属性,如果有符合IContributeServerContextSink/IContributeClientContextSink/IContributeObjectSink的,则把它用于扩展.
通常一个TransparentProxy的方法被调用,DotNet会调用RealProxy.PrivateInvoke为这个方法调用的堆栈影射为一个IMethodCallMessage,并且由RealProxy.Invoke进行具体对IMethodCallMessage的执行.对于常规的RemotingProxy,它则是根据这个TrapsparentProxy的 ChannelSink 进行封送(如果是跨Context的,则先用CrossContextChannelSink送到目标的Context , ContextBoundObject就是这样形成Context边界的) .
只要在一个类型上定义这个IContributeServerContextSink/IContributeClientContextSink/IContributeObjectSink的Attribute,则就能在封送过程中插入自定义的一步.
ContextBoundModel 本来是继承ProxyAttribute来创建目的对象的. 但目前发现和ServicedComponent/Context 并不兼容.
主要是我在原Context上直接创建对象了.并且把其他的IXXXAttribute的功能忽略掉!
一直都没有出现问题的原因是我没有对这些东西并进来进行测试。
所以这几天可能会改动为IContributeServerContextSink/IContributeClientContextSink/IContributeObjectSink的实现.
MSDN 上刚好有一篇同时讲这两个的文章:
Decouple Components by Injecting Custom Services into Your Object's Interception Chain
(里面提到的例子 LogBook 就是一个 AOP 思想的应用.)