示例#1
0
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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));
        }
示例#4
0
        /// <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));
        }
示例#5
0
        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);
        }
示例#6
0
        /// <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()));
        }
示例#7
0
        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);
        }