This class implements an event sink for a particular RCW. Unlike the implementation of events in TlbImp'd assemblies, we will create only one event sink per RCW (theoretically RCW might have several ComEventSink evenk sinks - but all these implement different source intefaces). Each ComEventSink contains a list of ComEventSinkMethod objects - which represent a single method on the source interface an a multicast delegate to redirect the calls. Notice that we are chaining multicast delegates so that same ComEventSinkMedhod can invoke multiple event handlers). ComEventSink implements an IDisposable pattern to Unadvise from the connection point. Typically, when RCW is finalized the corresponding Dispose will be triggered by ComEventSinksContainer finalizer. Notice that lifetime of ComEventSinksContainer is bound to the lifetime of the RCW.
Inheritance: System.MarshalByRefObject, IReflect, IDisposable
Exemple #1
0
        /// <summary>
        /// Adds a handler to an event.
        /// </summary>
        /// <param name="handler">The handler to be added.</param>
        /// <returns>The original event with handler added.</returns>
        private object InPlaceAdd(object handler)
        {
            ContractUtils.RequiresNotNull(handler, "handler");
            VerifyHandler(handler);

            ComEventSink comEventSink = ComEventSink.FromRuntimeCallableWrapper(_rcw, _sourceIid, true);

            comEventSink.AddHandler(_dispid, handler);
            return(this);
        }
Exemple #2
0
        /// <summary>
        /// Removes handler from the event.
        /// </summary>
        /// <param name="handler">The handler to be removed.</param>
        /// <returns>The original event with handler removed.</returns>
        private object InPlaceSubtract(object handler)
        {
            ContractUtils.RequiresNotNull(handler, nameof(handler));
            VerifyHandler(handler);

            ComEventSink comEventSink = ComEventSink.FromRuntimeCallableWrapper(_rcw, _sourceIid, false);

            comEventSink?.RemoveHandler(_dispid, handler);

            return(this);
        }
Exemple #3
0
        public static ComEventSink FromRuntimeCallableWrapper(object rcw, Guid sourceIid, bool createIfNotFound)
        {
            List <ComEventSink> comEventSinks = ComEventSinksContainer.FromRuntimeCallableWrapper(rcw, createIfNotFound);

            if (comEventSinks == null)
            {
                return(null);
            }

            ComEventSink comEventSink = null;

            lock (comEventSinks) {
                foreach (ComEventSink sink in comEventSinks)
                {
                    if (sink._sourceIid == sourceIid)
                    {
                        comEventSink = sink;
                        break;
                    }

                    if (sink._sourceIid == Guid.Empty)
                    {
                        // we found a ComEventSink object that
                        // was previously disposed. Now we will reuse it.
                        sink.Initialize(rcw, sourceIid);
                        comEventSink = sink;
                    }
                }

                if (comEventSink == null && createIfNotFound)
                {
                    comEventSink = new ComEventSink(rcw, sourceIid);
                    comEventSinks.Add(comEventSink);
                }
            }

            return(comEventSink);
        }
Exemple #4
0
        public static ComEventSink FromRuntimeCallableWrapper(object rcw, Guid sourceIid, bool createIfNotFound) {
            List<ComEventSink> comEventSinks = ComEventSinksContainer.FromRuntimeCallableWrapper(rcw, createIfNotFound);

            if (comEventSinks == null) {
                return null;
            }

            ComEventSink comEventSink = null;
            lock (comEventSinks) {

                foreach (ComEventSink sink in comEventSinks) {
                    if (sink._sourceIid == sourceIid) {
                        comEventSink = sink;
                        break;
                    } else if (sink._sourceIid == Guid.Empty) {
                        // we found a ComEventSink object that 
                        // was previously disposed. Now we will reuse it.
                        sink.Initialize(rcw, sourceIid);
                        comEventSink = sink;
                    }
                }

                if (comEventSink == null && createIfNotFound == true) {
                    comEventSink = new ComEventSink(rcw, sourceIid);
                    comEventSinks.Add(comEventSink);
                }
            }

            return comEventSink;
        }
 public ComEventSinkProxy(ComEventSink sink, Guid sinkIid)
     : base(typeof(ComEventSink))
 {
     _sink    = sink;
     _sinkIid = sinkIid;
 }
Exemple #6
0
 public ComEventSinkProxy(ComEventSink sink, Guid sinkIid)
     : base(typeof(ComEventSink)) {
     _sink = sink;
     _sinkIid = sinkIid;
 }