/// <summary> /// Detach this policy from given (censored) capability. /// </summary> /// <typeparam name="TCap">Capability interface type</typeparam> /// <param name="policy">Policy to detach</param> /// <param name="cap">Capability to clean</param> /// <returns>Clean capability instance (at least, without this interception policy)</returns> /// <exception cref="ArgumentNullException"><paramref name="policy"/> is null or /// <paramref name="cap"/> is null</exception> public static TCap Detach <TCap>(this IInterceptionPolicy policy, TCap cap) where TCap : class { if (policy == null) { throw new ArgumentNullException(nameof(policy)); } if (cap == null) { throw new ArgumentNullException(nameof(cap)); } switch (cap) { case Proxy proxy: return((CapabilityReflection.CreateProxy <TCap>(Detach(policy, proxy.ConsumedCap !)) as TCap) !); case CensorCapability ccap: { CensorCapability?cur = ccap; var stk = new Stack <IInterceptionPolicy>(); do { if (policy.Equals(cur.Policy)) { var cur2 = cur.InterceptedCapability; foreach (var p in stk) { cur2 = p.Attach(cur2); } return((cur2 as TCap) !); } stk.Push(cur.Policy); cur = cur.InterceptedCapability as CensorCapability; }while (cur != null); return((ccap as TCap) !); } default: return(cap); } }
/// <summary> /// Attach this policy to given capability. /// </summary> /// <typeparam name="TCap">Capability interface type</typeparam> /// <param name="policy">Policy to attach</param> /// <param name="cap">Capability to censor</param> /// <returns>Censored capability instance</returns> /// <exception cref="ArgumentNullException"><paramref name="policy"/> is null or /// <paramref name="cap"/> is null</exception> public static TCap Attach <TCap>(this IInterceptionPolicy policy, TCap cap) where TCap : class { if (policy == null) { throw new ArgumentNullException(nameof(policy)); } if (cap == null) { throw new ArgumentNullException(nameof(cap)); } var cur = cap as CensorCapability; while (cur != null) { if (policy.Equals(cur.Policy)) { return(cap); } cur = cur.InterceptedCapability as CensorCapability; } switch (cap) { case Proxy proxy: return((CapabilityReflection.CreateProxy <TCap>( Attach(policy, proxy.ConsumedCap !)) as TCap) !); case ConsumedCapability ccap: return((new CensorCapability(ccap, policy) as TCap) !); default: var temp = (CapabilityReflection.CreateProxy <TCap>( CapabilityReflection.CreateSkeletonInternal(cap).AsCapability())) as TCap; return(Attach(policy, temp !) !); } }