/********************************************************************++ Copyright (c) Microsoft Corporation. All rights reserved. --********************************************************************/ #if !SILVERLIGHT // ComObject #if !CLR2 using System.Linq.Expressions; #else using Microsoft.Scripting.Ast; #endif using System.Dynamic; //using Microsoft.Scripting.Utils; namespace System.Management.Automation.ComInterop { internal sealed class BoundDispEvent : DynamicObject { private object _rcw; private Guid _sourceIid; private int _dispid; internal BoundDispEvent(object rcw, Guid sourceIid, int dispid) { _rcw = rcw; _sourceIid = sourceIid; _dispid = dispid; } /// /// Provides the implementation of performing AddAssign and SubtractAssign binary operations. /// /// The binder provided by the call site. /// The handler for the operation. /// The result of the operation. /// true if the operation is complete, false if the call site should determine behavior. public override bool TryBinaryOperation(BinaryOperationBinder binder, object handler, out object result) { if (binder.Operation == ExpressionType.AddAssign) { result = InPlaceAdd(handler); return true; } if (binder.Operation == ExpressionType.SubtractAssign) { result = InPlaceSubtract(handler); return true; } result = null; return false; } private static void VerifyHandler(object handler) { if (handler is Delegate && handler.GetType() != typeof(Delegate)) { return; // delegate } if (handler is IDynamicMetaObjectProvider) { return; // IDMOP } if (handler is DispCallable) { return; } throw Error.UnsupportedHandlerType(); } /// /// Adds a handler to an event. /// /// The handler to be added. /// The original event with handler added. private object InPlaceAdd(object handler) { VerifyHandler(handler); ComEventSink comEventSink = ComEventSink.FromRuntimeCallableWrapper(_rcw, _sourceIid, true); comEventSink.AddHandler(_dispid, handler); return this; } /// /// Removes handler from the event. /// /// The handler to be removed. /// The original event with handler removed. private object InPlaceSubtract(object handler) { VerifyHandler(handler); ComEventSink comEventSink = ComEventSink.FromRuntimeCallableWrapper(_rcw, _sourceIid, false); if (comEventSink != null) { comEventSink.RemoveHandler(_dispid, handler); } return this; } } } #endif