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; } }
/*----------------------------------------------------------------------------------------*/ #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; }
/// <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)); } }
/*----------------------------------------------------------------------------------------*/ #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 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); } }
/// <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; }