public void CanCreateMethodInjector() { MethodInfo method = typeof(MethodInvocationObject).GetMethod("Foo"); IMethodInjector injector = Factory.GetInjector(method); Assert.That(injector, Is.Not.Null); }
/// <summary> /// Initializes a new instance of the <see cref="Invocation"/> class. /// </summary> /// <param name="request">The request, which describes the method call.</param> /// <param name="injector">The injector that will be used to call the target method.</param> /// <param name="interceptors">The chain of interceptors that will be executed before the target method is called.</param> public Invocation( IProxyRequest request, IMethodInjector injector, IEnumerable<IInterceptor> interceptors ) : base( request, interceptors ) { Ensure.ArgumentNotNull( injector, "injector" ); Injector = injector; }
/// <summary> /// Initializes a new instance of the <see cref="Invocation"/> class. /// </summary> /// <param name="request">The request, which describes the method call.</param> /// <param name="injector">The injector that will be used to call the target method.</param> /// <param name="interceptors">The chain of interceptors that will be executed before the target method is called.</param> public Invocation(IProxyRequest request, IMethodInjector injector, IEnumerable <IInterceptor> interceptors) : base(request, interceptors) { Ensure.ArgumentNotNull(injector, "injector"); Injector = injector; }
/*----------------------------------------------------------------------------------------*/ #region Public Methods /// <summary> /// Creates an executable invocation for the specified request. /// </summary> /// <param name="request">The request.</param> /// <returns>An executable invocation representing the specified request.</returns> public virtual IInvocation CreateInvocation(IRequest request) { IComponentContainer components = request.Context.Binding.Components; IEnumerable <IInterceptor> interceptors = components.AdviceRegistry.GetInterceptors(request); IMethodInjector injector = components.InjectorFactory.GetInjector(request.Method); return(new StandardInvocation(request, injector, interceptors)); }
/*----------------------------------------------------------------------------------------*/ #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> /// 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, IMethodInjector injector, DeliveryThread thread) { Ensure.NotDisposed(this); var factory = Kernel.Components.Get <IMessageSubscriptionFactory>(); lock (_subscriptions) { _subscriptions.Add(factory.Create(this, subscriber, injector, thread)); } }
/*----------------------------------------------------------------------------------------*/ #region Disposal /// <summary> /// Releases all resources held by the object. /// </summary> /// <param name="disposing"><see langword="True"/> if managed objects should be disposed, otherwise <see langword="false"/>.</param> protected override void Dispose(bool disposing) { if (disposing && !IsDisposed) { _channel = null; _subscriber = null; _injector = null; } base.Dispose(disposing); }
/// <summary> /// Creates an executable invocation for the specified request. /// </summary> /// <param name="request">The request.</param> /// <returns>An executable invocation representing the specified request.</returns> public virtual IInvocation CreateInvocation(IProxyRequest request) { IComponentContainer components = request.Context.Kernel.Components; IEnumerable <IInterceptor> interceptors = components.Get <IAdviceRegistry>().GetInterceptors(request); IMethodInjector injector = components.Get <IInjectorFactory>().GetInjector(request.Method); return(new Invocation.Invocation(request, injector, interceptors)); }
public void ExceptionInInjectedMethodIsThrownProperly() { MethodInfo method = typeof(ThrowsExceptionFromInjectedMethod).GetMethod("Foo"); IMethodInjector injector = Factory.GetInjector(method); Assert.That(injector, Is.Not.Null); ThrowsExceptionFromInjectedMethod mock = new ThrowsExceptionFromInjectedMethod(); injector.Invoke(mock, new object[0]); }
public void MethodInjectorCanReturnReferenceType() { MethodInfo method = typeof(MethodInvocationObject).GetMethod("Foo"); IMethodInjector injector = Factory.GetInjector(method); Assert.That(injector, Is.Not.Null); MethodInvocationObject mock = new MethodInvocationObject(); string result = (string)injector.Invoke(mock, new object[] { 42 }); Assert.That(result, Is.EqualTo("42")); }
public void MethodInjectorCanReturnValueType() { MethodInfo method = typeof(MethodInvocationObject).GetMethod("Boink"); IMethodInjector injector = Factory.GetInjector(method); Assert.That(injector, Is.Not.Null); MethodInvocationObject mock = new MethodInvocationObject(); int result = (int)injector.Invoke(mock, new object[] { 12 }); Assert.That(result, Is.EqualTo(120)); }
public void MethodInjectorCanCallGenericMethod() { MethodInfo gtd = typeof(ObjectWithGenericMethod).GetMethod("ConvertGeneric"); MethodInfo method = gtd.MakeGenericMethod(typeof(int)); IMethodInjector injector = Factory.GetInjector(method); Assert.That(injector, Is.Not.Null); ObjectWithGenericMethod obj = new ObjectWithGenericMethod(); string result = injector.Invoke(obj, new object[] { 42 }) as string; Assert.That(result, Is.EqualTo("42")); }
/*----------------------------------------------------------------------------------------*/ #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 }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Removes a subscription from the channel. /// </summary> /// <param name="subscriber">The object that is subscribing to events.</param> /// <param name="injector">The injector associated with the subscription.</param> /// <returns><see langword="true"/> if the subscription was removed, or <see langword="false"/> if no such publication exists.</returns> public bool RemoveSubscription(object subscriber, IMethodInjector injector) { Ensure.NotDisposed(this); lock (_subscriptions) { foreach (IMessageSubscription subscription in _subscriptions) { if ((subscription.Subscriber == subscriber) && (subscription.Injector.Member == injector.Member)) { _subscriptions.Remove(subscription); return(true); } } } return(false); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Gets an injector for the specified method. /// </summary> /// <param name="method">The method that the injector will invoke.</param> /// <returns>A new injector for the method.</returns> public IMethodInjector GetInjector(MethodInfo method) { lock (_methodInjectors) { if (method.IsGenericMethodDefinition) { throw new InvalidOperationException(ExceptionFormatter.CannotCreateInjectorFromGenericTypeDefinition(method)); } if (_methodInjectors.ContainsKey(method)) { return(_methodInjectors[method]); } IMethodInjector injector = CreateInjector(method); _methodInjectors.Add(method, injector); return(injector); } }
/// <summary> /// Gets an injector for the specified method. /// </summary> /// <param name="method">The method that the injector will invoke.</param> /// <returns>A new injector for the method.</returns> public IMethodInjector GetInjector(MethodInfo method) { lock ( _methodInjectors ) { /*if ( method.IsGenericMethodDefinition ) * { * throw new InvalidOperationException(); * }*/ if (_methodInjectors.ContainsKey(method)) { return(_methodInjectors[method]); } IMethodInjector injector = CreateInjector(method); _methodInjectors.Add(method, injector); return(injector); } }
public void InjectorFactoryIsThreadSafe() { MethodInfo method = typeof(MethodInvocationObject).GetMethod("Foo"); IMethodInjector injector1 = null; IMethodInjector injector2 = null; var thread1 = new Thread(x => injector1 = Factory.GetInjector(method)); var thread2 = new Thread(x => injector2 = Factory.GetInjector(method)); thread1.Start(); thread2.Start(); thread1.Join(); thread2.Join(); Assert.That(injector1, Is.Not.Null); Assert.That(injector2, Is.Not.Null); Assert.That(injector1, Is.SameAs(injector2)); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Executed when the instance is being initialized. /// </summary> /// <param name="context">The activation context.</param> /// <returns>A value indicating whether to proceed or stop the execution of the strategy chain.</returns> public override StrategyResult Initialize(IContext context) { IList <MethodInjectionDirective> directives = context.Plan.Directives.GetAll <MethodInjectionDirective>(); if (directives.Count > 0) { var injectorFactory = context.Binding.Components.InjectorFactory; foreach (MethodInjectionDirective directive in directives) { // Resolve the arguments that should be injected via the method's arguments. object[] arguments = ResolveArguments(context, directive); // Get an injector that can call the method. IMethodInjector injector = injectorFactory.GetInjector(directive.Member); // Call the method. injector.Invoke(context.Instance, arguments); } } return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Executed to build the activation plan. /// </summary> /// <param name="binding">The binding that points at the type whose activation plan is being released.</param> /// <param name="type">The type whose activation plan is being manipulated.</param> /// <param name="plan">The activation plan that is being manipulated.</param> /// <returns> /// A value indicating whether to proceed or interrupt the strategy chain. /// </returns> public override StrategyResult Build(IBinding binding, Type type, IActivationPlan plan) { EventInfo[] events = type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); foreach (EventInfo evt in events) { #if !MONO PublishAttribute[] attributes = evt.GetAllAttributes <PublishAttribute>(); #else PublishAttribute[] attributes = ExtensionsForICustomAttributeProvider.GetAllAttributes <PublishAttribute>(evt); #endif foreach (PublishAttribute attribute in attributes) { plan.Directives.Add(new PublicationDirective(attribute.Channel, evt)); } } MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); var injectorFactory = binding.Components.Get <IInjectorFactory>(); foreach (MethodInfo method in methods) { #if !MONO SubscribeAttribute[] attributes = method.GetAllAttributes <SubscribeAttribute>(); #else SubscribeAttribute[] attributes = ExtensionsForICustomAttributeProvider.GetAllAttributes <SubscribeAttribute>(method); #endif foreach (SubscribeAttribute attribute in attributes) { IMethodInjector injector = injectorFactory.GetInjector(method); plan.Directives.Add(new SubscriptionDirective(attribute.Channel, injector, attribute.Thread)); } } return(StrategyResult.Proceed); }
/*----------------------------------------------------------------------------------------*/ /// <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, IMethodInjector 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 }
/*----------------------------------------------------------------------------------------*/ /// <summary> /// Removes a subscription from the channel. /// </summary> /// <param name="subscriber">The object that is subscribing to events.</param> /// <param name="injector">The injector associated with the subscription.</param> /// <returns><see langword="true"/> if the subscription was removed, or <see langword="false"/> if no such publication exists.</returns> public bool RemoveSubscription(object subscriber, IMethodInjector injector) { Ensure.NotDisposed(this); lock (_subscriptions) { foreach (IMessageSubscription subscription in _subscriptions) { if ((subscription.Subscriber == subscriber) && (subscription.Injector.Member == injector.Member)) { _subscriptions.Remove(subscription); return true; } } } return false; }
/*----------------------------------------------------------------------------------------*/ /// <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)); }