public void ShouldResolveConstructorWithAdditionalArgument() { var mockSampleService = new Mock <ISampleService>(); IServiceContainer container = new ServiceContainer(); // Add an ISampleService instance container.AddService(mockSampleService.Object); container.AddDefaultServices(); var resolver = container.GetService <IMemberResolver <ConstructorInfo> >(); Assert.IsNotNull(resolver); // The resolver should return the constructor // with the following signature: Constructor(ISampleService, int) ConstructorInfo expectedConstructor = typeof(SampleClassWithAdditionalArgument).GetConstructor(new[] { typeof(ISampleService), typeof(int) }); Assert.IsNotNull(expectedConstructor); var context = new MethodFinderContext(42); ConstructorInfo result = resolver.ResolveFrom(typeof(SampleClassWithAdditionalArgument), container, context); Assert.AreSame(expectedConstructor, result); }
public void ShouldResolveConstructorWithMostResolvableParametersFromContainer() { var mockSampleService = new Mock <ISampleService>(); IServiceContainer container = new ServiceContainer(); // Add an ISampleService instance container.AddService(mockSampleService.Object); container.AddDefaultServices(); var resolver = container.GetService <IMemberResolver <ConstructorInfo> >(); Assert.IsNotNull(resolver); // The resolver should return the constructor with two ISampleService parameters ConstructorInfo expectedConstructor = typeof(SampleClassWithMultipleConstructors).GetConstructor(new[] { typeof(ISampleService), typeof(ISampleService) }); Assert.IsNotNull(expectedConstructor); var finderContext = new MethodFinderContext(new Type[0], new object[0], null); ConstructorInfo result = resolver.ResolveFrom(typeof(SampleClassWithMultipleConstructors), container, finderContext); Assert.AreSame(expectedConstructor, result); }
/// <summary> /// Invokes a method on the target <paramref name="instance"/> using the given <paramref name="methodName"/>. /// </summary> /// <param name="instance">The target instance.</param> /// <param name="methodName">The name of the target method.</param> /// <param name="typeArguments">The type arguments that will be passed to the target method.</param> /// <param name="arguments">The arguments that will be passed to the target method.</param> /// <returns>The method return value.</returns> public static object Invoke(this object instance, string methodName, Type[] typeArguments, params object[] arguments) { var context = new MethodFinderContext(typeArguments, arguments, null); return(Invoke(instance, methodName, context)); }
/// <summary> /// Invokes a method on the target <paramref name="instance"/>. /// </summary> /// <param name="instance">The target instance that will be used to invoke the method.</param> /// <param name="methodName">The name of the target method.</param> /// <param name="arguments">The arguments that will be passed to the target method.</param> /// <returns>The method return value.</returns> public static object Invoke(this object instance, string methodName, params object[] arguments) { if (instance == null) { throw new NullReferenceException("instance"); } var context = new MethodFinderContext(arguments); return(Invoke(instance, methodName, context)); }
public void ShouldFindGenericMethod() { var container = new ServiceContainer(); container.LoadFromBaseDirectory("*.dll"); var context = new MethodFinderContext(new Type[] { typeof(object) }, new object[0], typeof(void)); var methods = typeof(SampleClassWithGenericMethod).GetMethods(BindingFlags.Public | BindingFlags.Instance); var finder = container.GetService <IMethodFinder <MethodInfo> >(); var result = finder.GetBestMatch(methods, context); Assert.IsTrue(result.IsGenericMethod); Assert.IsTrue(result.GetGenericArguments().Count() == 1); }
/// <summary> /// Invokes a method on the target <paramref name="instance"/> using the given <paramref name="methodName"/> and <paramref name="context"/>. /// </summary> /// <param name="instance">The target instance.</param> /// <param name="methodName">The name of the target method.</param> /// <param name="context">The <see cref="IMethodFinderContext"/> that describes the target method.</param> /// <returns>The method return value.</returns> public static object Invoke(this object instance, string methodName, MethodFinderContext context) { Type targetType = instance.GetType(); BindingFlags flags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic; // Group the methods by name var methodMap = new Dictionary <string, List <MethodInfo> >(); MethodInfo[] methods = targetType.GetMethods(flags); foreach (MethodInfo method in methods) { string name = method.Name; if (!methodMap.ContainsKey(name)) { methodMap[name] = new List <MethodInfo>(); } List <MethodInfo> currentList = methodMap[name]; currentList.Add(method); } List <MethodInfo> targetMethods = methodMap.ContainsKey(methodName) ? methodMap[methodName] : (new MethodInfo[0]).ToList(); var finder = _container.GetService <IMethodFinder <MethodInfo> >(); MethodInfo targetMethod = finder.GetBestMatch(targetMethods, context); // Search the methods that match the given method name if (targetMethod == null || targetMethods.Count == 0) { string message = string.Format("Method '{0}' not found on type '{1}'", methodName, targetType); throw new ArgumentException(message, "methodName"); } // Instantiate the generic method, if necessary if (targetMethod.ContainsGenericParameters) { targetMethod = targetMethod.MakeGenericMethod(context.TypeArguments.ToArray()); } var invoker = _container.GetService <IMethodInvoke <MethodInfo> >(); return(invoker.Invoke(instance, targetMethod, context.Arguments.ToArray())); }
public override bool TryInvoke(InvokeBinder binder, object[] args, out object result) { var finder = new MethodBaseFinder <MethodInfo>(); var context = new MethodFinderContext(Option.None <string>(), args); var delegatesByMethod = _delegates.ToDictionary(d => d.Method); var methods = delegatesByMethod.Keys; result = null; var bestMatch = finder.GetBestMatch(methods, context); if (!bestMatch.HasValue) { return(false); } var targetMethod = bestMatch.ValueOrFailure(); var targetDelegate = delegatesByMethod[targetMethod]; result = targetMethod.Invoke(targetDelegate.Target, args); return(true); }