private static void Deliver(
            MethodInfo method,
            object target,
            DeliveryThread deliveryThread,
            object sender,
            EventArgs args
#if !NETCF
            , SynchronizationContext context
#endif
            )
        {
            switch (deliveryThread)
            {
            case DeliveryThread.Background:
                DeliverViaBackgroundThread(method, target, sender, args);
                break;

#if !NETCF
            case DeliveryThread.UserInterface:
                DeliverViaSynchronizationContext(method, context, target, sender, args);
                break;
#endif
            default:
                DeliverMessage(method, target, sender, args);
                break;
            }
        }
예제 #2
0
        /*----------------------------------------------------------------------------------------*/
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="SubscriptionDirective"/> class.
        /// </summary>
        /// <param name="channel">The name of the channel that is to be susbcribed to.</param>
        /// <param name="injector">The injector that triggers the method.</param>
        /// <param name="thread">The thread on which the message should be delivered.</param>
        public SubscriptionDirective(string channel, IMethodInjector injector, DeliveryThread thread)
        {
            Ensure.ArgumentNotNullOrEmptyString(channel, "channel");
            Ensure.ArgumentNotNull(injector, "injector");

            _channel  = channel;
            _injector = injector;
            _thread   = thread;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="SubscriptionDirective"/> class.
        /// </summary>
        /// <param name="channel">The name of the channel that is to be susbcribed to.</param>
        /// <param name="injector">The injector that triggers the method.</param>
        /// <param name="thread">The thread on which the message should be delivered.</param>
        public SubscriptionDirective( string channel, MethodInjector injector, DeliveryThread thread )
        {
            Ensure.ArgumentNotNullOrEmpty( channel, "channel" );
            Ensure.ArgumentNotNull( injector, "injector" );

            _channel = channel;
            _injector = injector;
            _thread = thread;
        }
예제 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="instance"></param>
 /// <param name="method"></param>
 /// <param name="thread"></param>
 public void AddSubscription(object instance, MethodInfo method, DeliveryThread thread)
 {
     lock (_subscriptions)
     {
         var entry = new TransportCacheEntry(TransportProvider.GetTransport(method, thread),
                                             new WeakReference(instance));
         _subscriptions.Add(entry);
     }
 }
        /// <summary>
        /// Adds a subscription to the channel.
        /// </summary>
        /// <param name="subscriber">The object that will subscribe to events.</param>
        /// <param name="injector">The injector that will be triggered when an event occurs.</param>
        /// <param name="thread">The thread on which the message should be delivered.</param>
        public void AddSubscription(object subscriber, MethodInjector injector, DeliveryThread thread)
        {
            Ensure.NotDisposed(this);

            var factory = Kernel.Components.Get <IMessageSubscriptionFactory>();

            lock ( _subscriptions )
            {
                _subscriptions.Add(factory.Create(this, subscriber, injector, thread));
            }
        }
예제 #6
0
        /*----------------------------------------------------------------------------------------*/
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="StandardMessageSubscription"/> class.
        /// </summary>
        /// <param name="channel">The channel associated with the subscription.</param>
        /// <param name="subscriber">The object that will receive the channel events.</param>
        /// <param name="injector">The injector that will be triggered an event occurs.</param>
        /// <param name="deliveryThread">The thread context that should be used to deliver the message.</param>
        public StandardMessageSubscription(IMessageChannel channel, object subscriber, IMethodInjector injector,
                                           DeliveryThread deliveryThread)
        {
            _channel        = channel;
            _subscriber     = subscriber;
            _injector       = injector;
            _deliveryThread = deliveryThread;

#if !SILVERLIGHT
            if (deliveryThread == DeliveryThread.UserInterface)
            {
                _syncContext = SynchronizationContext.Current;
            }
#endif
        }
        internal static Action<WeakReference, object, EventArgs> GetTransport(MethodInfo method, DeliveryThread deliveryThread)
        {
#if SILVERLIGHT || NETCF
            lock (SyncRoot)
            {
                Action<WeakReference, object, EventArgs> existingTransport;
                if ( Transports.TryGetValue( method, out existingTransport ) )
                {
                    return existingTransport;
                }
                GuardAgainstClosures( method );
                Action<WeakReference, object, EventArgs> transport = CreateTransportMethod( method, deliveryThread );
                Transports[method] = transport;
                return transport;
            }
#else
            TransportLock.EnterUpgradeableReadLock();
            try
            {
                Action<WeakReference, object, EventArgs> existingTransport;
                if ( Transports.TryGetValue( method, out existingTransport ) )
                {
                    return existingTransport;
                }
                TransportLock.EnterWriteLock();
                try
                {
                    GuardAgainstClosures( method );
                    Action<WeakReference, object, EventArgs> transport = CreateTransportMethod( method, deliveryThread );
                    Transports[method] = transport;
                    return transport;
                }
                finally
                {
                    TransportLock.ExitWriteLock();
                }
            }
            finally
            {
                TransportLock.ExitUpgradeableReadLock();
            }
#endif // SILVERLIGHT || NETCF
        }
        private static void Deliver(
            MethodInfo method, 
            object target, 
            DeliveryThread deliveryThread, 
            object sender, 
            EventArgs args
#if !NETCF
            , SynchronizationContext context
#endif
            )
        {
            switch (deliveryThread)
            {
                case DeliveryThread.Background:
                    DeliverViaBackgroundThread(method, target, sender, args);
                    break;
#if !NETCF
                case DeliveryThread.UserInterface:
                    DeliverViaSynchronizationContext(method, context, target, sender, args);
                    break;
#endif
                default:
                    DeliverMessage(method, target, sender, args);
                    break;
            }
        }
        private static Action <WeakReference, object, EventArgs> CreateTransportMethod(MethodInfo method, DeliveryThread deliveryThread)
        {
#if NO_LCG
            return(ReflectionTransportGenerator(method, deliveryThread));
#else
            return(DynamicTransportGenerator(method, deliveryThread));
#endif
        }
        internal static Action<WeakReference, object, EventArgs> DynamicTransportGenerator(MethodInfo method, DeliveryThread deliveryThread)
        {
            var dynamicMethod = new DynamicMethod( GetAnonymousMethodName(), null, Parameters, method.DeclaringType, true );

            ILGenerator il = dynamicMethod.GetILGenerator();
            if ( !method.IsStatic )
            {
                ILEmitter.EmitGuardCondition( il, method, GetTarget );
            }
            ILEmitter.EmitEventHandlerMethodCall( il, method, new[] {OpCodes.Ldarg_1, OpCodes.Ldarg_2} );
            ILEmitter.EmitReturn( il );

            var action = (Action<WeakReference, object, EventArgs>)dynamicMethod.CreateDelegate(typeof(Action<WeakReference, object, EventArgs>));

            switch (deliveryThread)
            {
                case DeliveryThread.Background:
                    return (weakReference, parameters, e) => ThreadPool.QueueUserWorkItem(s => action(weakReference, parameters, e));
#if !NETCF
                case DeliveryThread.UserInterface:
                    var context = SynchronizationContext.Current;
                    if (context != null)
                    {
                        return (weakReference, parameters, e) => context.Send(delegate { action(weakReference, parameters, e); }, null);
                    }

                    goto default;
#endif
                default:
                    return action;
            }
        }
        internal static Action<WeakReference, object, EventArgs> ReflectionTransportGenerator(MethodInfo method, DeliveryThread deliveryThread)
        {
#if !NETCF
            SynchronizationContext context = null;
            if (deliveryThread == DeliveryThread.UserInterface)
            {
                context = SynchronizationContext.Current;
            }
#endif
            return ( weakReference, sender, args ) =>
                   {
                       object target = null;
                       if ( !method.IsStatic )
                       {
                           target = GetTarget.Invoke( weakReference, null );
                           if ( target == null )
                           {
                               return;
                           }
                       }
#if !NETCF
                       Deliver(method, target, deliveryThread, sender, args, context);
#else
                       Deliver(method, target, deliveryThread, sender, args);
#endif
                       
                   };
        }
        internal static Action <WeakReference, object, EventArgs> GetTransport(MethodInfo method, DeliveryThread deliveryThread)
        {
#if SILVERLIGHT || NETCF
            lock (SyncRoot)
            {
                Action <WeakReference, object, EventArgs> existingTransport;
                if (Transports.TryGetValue(method, out existingTransport))
                {
                    return(existingTransport);
                }
                GuardAgainstClosures(method);
                Action <WeakReference, object, EventArgs> transport = CreateTransportMethod(method, deliveryThread);
                Transports[method] = transport;
                return(transport);
            }
#else
            TransportLock.EnterUpgradeableReadLock();
            try
            {
                Action <WeakReference, object, EventArgs> existingTransport;
                if (Transports.TryGetValue(method, out existingTransport))
                {
                    return(existingTransport);
                }
                TransportLock.EnterWriteLock();
                try
                {
                    GuardAgainstClosures(method);
                    Action <WeakReference, object, EventArgs> transport = CreateTransportMethod(method, deliveryThread);
                    Transports[method] = transport;
                    return(transport);
                }
                finally
                {
                    TransportLock.ExitWriteLock();
                }
            }
            finally
            {
                TransportLock.ExitUpgradeableReadLock();
            }
#endif // SILVERLIGHT || NETCF
        }
        private static Action<WeakReference, object, EventArgs> CreateTransportMethod( MethodInfo method, DeliveryThread deliveryThread )
        {
#if NO_LCG
            return ReflectionTransportGenerator( method, deliveryThread );
#else
            return DynamicTransportGenerator( method, deliveryThread );
#endif
        }
        internal static Action <WeakReference, object, EventArgs> ReflectionTransportGenerator(MethodInfo method, DeliveryThread deliveryThread)
        {
#if !NETCF
            SynchronizationContext context = null;
            if (deliveryThread == DeliveryThread.UserInterface)
            {
                context = SynchronizationContext.Current;
            }
#endif
            return((weakReference, sender, args) =>
            {
                object target = null;
                if (!method.IsStatic)
                {
                    target = GetTarget.Invoke(weakReference, null);
                    if (target == null)
                    {
                        return;
                    }
                }
#if !NETCF
                Deliver(method, target, deliveryThread, sender, args, context);
#else
                Deliver(method, target, deliveryThread, sender, args);
#endif
            });
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="instance"></param>
 /// <param name="method"></param>
 /// <param name="thread"></param>
 public void AddSubscription( object instance, MethodInfo method, DeliveryThread thread )
 {
     lock (_subscriptions)
     {
         var entry = new TransportCacheEntry(TransportProvider.GetTransport(method, thread),
                                                       new WeakReference(instance));
         _subscriptions.Add(entry);
     }
 }
 /// <summary>
 /// Creates a subscription for the specified channel.
 /// </summary>
 /// <param name="channel">The channel that will be subscribed to.</param>
 /// <param name="subscriber">The object that will receive events from the channel.</param>
 /// <param name="injector">The injector that will be called to trigger the event handler.</param>
 /// <param name="deliveryThread">The thread on which the subscription will be delivered.</param>
 /// <returns>The newly-created subscription.</returns>
 public IMessageSubscription Create( IMessageChannel channel, object subscriber, MethodInjector injector,
                                     DeliveryThread deliveryThread )
 {
     return new StandardMessageSubscription( channel, subscriber, injector, deliveryThread );
 }
        /// <summary>
        /// Initializes a new instance of the <see cref="StandardMessageSubscription"/> class.
        /// </summary>
        /// <param name="channel">The channel associated with the subscription.</param>
        /// <param name="subscriber">The object that will receive the channel events.</param>
        /// <param name="injector">The injector that will be triggered an event occurs.</param>
        /// <param name="deliveryThread">The thread context that should be used to deliver the message.</param>
        public StandardMessageSubscription( IMessageChannel channel, object subscriber, MethodInjector injector,
                                            DeliveryThread deliveryThread )
        {
            _channel = channel;
            _subscriber = subscriber;
            _injector = injector;
            _deliveryThread = deliveryThread;

#if !SILVERLIGHT && !NETCF
            if ( deliveryThread == DeliveryThread.UserInterface )
            {
                _syncContext = SynchronizationContext.Current;
            }
#endif
        }
 /*----------------------------------------------------------------------------------------*/
 /// <summary>
 /// Creates a subscription for the specified channel.
 /// </summary>
 /// <param name="channel">The channel that will be subscribed to.</param>
 /// <param name="subscriber">The object that will receive events from the channel.</param>
 /// <param name="injector">The injector that will be called to trigger the event handler.</param>
 /// <param name="deliveryThread">The thread on which the subscription will be delivered.</param>
 /// <returns>The newly-created subscription.</returns>
 public IMessageSubscription Create(IMessageChannel channel, object subscriber, IMethodInjector injector,
                                    DeliveryThread deliveryThread)
 {
     return(new StandardMessageSubscription(channel, subscriber, injector, deliveryThread));
 }
        /// <summary>
        /// Adds a subscription to the channel.
        /// </summary>
        /// <param name="subscriber">The object that will subscribe to events.</param>
        /// <param name="injector">The injector that will be triggered when an event occurs.</param>
        /// <param name="thread">The thread on which the message should be delivered.</param>
        public void AddSubscription( object subscriber, MethodInjector injector, DeliveryThread thread )
        {
            Ensure.NotDisposed( this );

            var factory = Kernel.Components.Get<IMessageSubscriptionFactory>();

            lock ( _subscriptions )
            {
                _subscriptions.Add( factory.Create( this, subscriber, injector, thread ) );
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="SubscriptionDirective"/> class.
 /// </summary>
 /// <param name="channel">The channel.</param>
 /// <param name="methodInfo">The method info.</param>
 /// <param name="thread">The thread on which the message should be delivered.</param>
 public SubscriptionDirective( string channel, MethodInfo methodInfo, DeliveryThread thread )
 {
     Channel = channel;
     MethodInfo = methodInfo;
     Thread = thread;
 }
        internal static Action <WeakReference, object, EventArgs> DynamicTransportGenerator(MethodInfo method, DeliveryThread deliveryThread)
        {
            var dynamicMethod = new DynamicMethod(GetAnonymousMethodName(), null, Parameters, method.DeclaringType, true);

            ILGenerator il = dynamicMethod.GetILGenerator();

            if (!method.IsStatic)
            {
                ILEmitter.EmitGuardCondition(il, method, GetTarget);
            }
            ILEmitter.EmitEventHandlerMethodCall(il, method, new[] { OpCodes.Ldarg_1, OpCodes.Ldarg_2 });
            ILEmitter.EmitReturn(il);

            var action = (Action <WeakReference, object, EventArgs>)dynamicMethod.CreateDelegate(typeof(Action <WeakReference, object, EventArgs>));

            switch (deliveryThread)
            {
            case DeliveryThread.Background:
                return((weakReference, parameters, e) => ThreadPool.QueueUserWorkItem(s => action(weakReference, parameters, e)));

#if !NETCF
            case DeliveryThread.UserInterface:
                var context = SynchronizationContext.Current;
                if (context != null)
                {
                    return((weakReference, parameters, e) => context.Send(delegate { action(weakReference, parameters, e); }, null));
                }

                goto default;
#endif
            default:
                return(action);
            }
        }
예제 #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SubscriptionDirective"/> class.
 /// </summary>
 /// <param name="channel">The channel.</param>
 /// <param name="methodInfo">The method info.</param>
 /// <param name="thread">The thread on which the message should be delivered.</param>
 public SubscriptionDirective(string channel, MethodInfo methodInfo, DeliveryThread thread)
 {
     Channel    = channel;
     MethodInfo = methodInfo;
     Thread     = thread;
 }