static FastReflectionFactories() { MethodInvokerFactory = new MethodInvokerFactory(); PropertyAccessorFactory = new PropertyAccessorFactory(); FieldAccessorFactory = new FieldAccessorFactory(); ConstructorInvokerFactory = new ConstructorInvokerFactory(); }
public void Create_IfMultipleInputParameters_PassesInputArguments(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "TestIntStringObjectArray"); int expectedA = 1; string expectedB = "B"; object[] expectedC = new object[] { new object() }; // Act IMethodInvoker <MethodInvokerFactoryTests, object> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests, object>(method); // Assert Assert.NotNull(invoker); bool callbackCalled = false; Action <int, string, object> callback = (a, b, c) => { callbackCalled = true; Assert.Equal(expectedA, a); Assert.Same(expectedB, b); Assert.Same(expectedC, c); }; MethodInvokerFactoryTests instance = GetInstance(isInstance); object[] arguments = new object[] { expectedA, expectedB, expectedC, callback }; invoker.InvokeAsync(instance, arguments).GetAwaiter().GetResult(); Assert.True(callbackCalled); }
public void Create_IfInOutByRefMethodReturnsTask_RoundtripsArguments(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "TestInOutByRefReturnTask"); int expectedA = 1; string expectedInitialB = "B"; string expectedFinalB = "b"; object[] expectedC = new object[] { new object(), default(int), String.Empty }; // Act IMethodInvoker <MethodInvokerFactoryTests, object> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests, object>(method); // Assert Assert.NotNull(invoker); bool callbackCalled = false; InOutRefTaskFunc callback = delegate(int a, ref string b, out object[] c) { callbackCalled = true; Assert.Equal(expectedA, a); Assert.Same(expectedInitialB, b); b = expectedFinalB; c = expectedC; return(Task.FromResult(0)); }; MethodInvokerFactoryTests instance = GetInstance(isInstance); object[] arguments = new object[] { expectedA, expectedInitialB, null, callback }; invoker.InvokeAsync(instance, arguments).GetAwaiter().GetResult(); Assert.True(callbackCalled); Assert.Same(expectedFinalB, arguments[1]); Assert.Same(expectedC, arguments[2]); }
public void Create_IfMultipleOutputParameters_SetsOutputArguments(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "TestOutIntStringObjectArray"); int expectedA = 1; string expectedB = "B"; object[] expectedC = new object[] { new object() }; // Act IMethodInvoker <MethodInvokerFactoryTests, object> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests, object>(method); // Assert Assert.NotNull(invoker); bool callbackCalled = false; OutAction callback = delegate(out int a, out string b, out object[] c) { callbackCalled = true; a = expectedA; b = expectedB; c = expectedC; }; MethodInvokerFactoryTests instance = GetInstance(isInstance); object[] arguments = new object[] { default(int), null, null, callback }; invoker.InvokeAsync(instance, arguments).GetAwaiter().GetResult(); Assert.True(callbackCalled); Assert.Equal(expectedA, arguments[0]); Assert.Same(expectedB, arguments[1]); Assert.Same(expectedC, arguments[2]); }
public void Create_IfMethodReturnsNonTask_Throws() { // Arrange MethodInfo method = GetMethodInfo("ReturnInt"); // Act & Assert ExceptionAssert.ThrowsNotSupported(() => MethodInvokerFactory.Create <MethodInvokerFactoryTests>(method), "Methods may only return void or Task."); }
public void Create_IfTReflectedIsNotReflectedType_Throws(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "ReturnVoid"); // Act & Assert ExceptionAssert.ThrowsInvalidOperation(() => MethodInvokerFactory.Create <object>(method), "TReflected must match the method's ReflectedType."); }
public void Create_IfMethodIsNull_Throws() { // Arrange MethodInfo method = null; // Act & Assert ExceptionAssert.ThrowsArgumentNull(() => MethodInvokerFactory.Create <MethodInvokerFactoryTests>(method), "method"); }
/// <summary> /// 根据指定的MethodInfo以及参数数组,快速调用相关的方法。 /// </summary> /// <param name="methodInfo">MethodInfo实例成员</param> /// <param name="obj">目标实例成员</param> /// <param name="parameters">函数参数</param> /// <returns>调用结果</returns> public static object FastInvoke(this MethodInfo methodInfo, object obj, params object[] parameters) { if (methodInfo == null) { throw new ArgumentNullException("methodInfo"); } IInvokeMethod method = MethodInvokerFactory.GetMethodInvokerWrapper(methodInfo); return(method.Invoke(obj, parameters)); }
public void Create_IfStaticMethodReturnsVoid_ReturnsVoidInvoker(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "ReturnVoid"); // Act IMethodInvoker <MethodInvokerFactoryTests, object> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests, object>(method); // Assert Assert.IsType <VoidMethodInvoker <MethodInvokerFactoryTests, object> >(invoker); }
public void Create_IfStaticMethodReturnsTask_ReturnsTaskInvoker(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "ReturnTask"); // Act IMethodInvoker <MethodInvokerFactoryTests> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests>(method); // Assert Assert.IsType <TaskMethodInvoker <MethodInvokerFactoryTests> >(invoker); }
private void CreateTimersFromAssemblies(long tick) { // Find methods with TimerAttribute in any ISystem in any assembly. var events = new AssemblyScanner() .IncludeAllAssemblies() .IncludeNonPublicMembers() .Implements <ISystem>() .ScanMethods <TimerAttribute>(); // Create timer invokers and store timer info in registry. foreach (var(method, attribute) in events) { CoreLog.LogDebug("Adding timer on {0}.{1}.", method.DeclaringType, method.Name); if (!IsValidInterval(attribute.IntervalTimeSpan)) { CoreLog.Log(CoreLogLevel.Error, $"Timer {method} could not be registered the interval {attribute.IntervalTimeSpan} is invalid."); continue; } var service = _serviceProvider.GetService(method.DeclaringType); if (service == null) { CoreLog.Log(CoreLogLevel.Debug, "Skipping timer registration because service could not be loaded."); continue; } var parameterInfos = method.GetParameters() .Select(info => new MethodParameterSource(info) { IsService = true }) .ToArray(); var compiled = MethodInvokerFactory.Compile(method, parameterInfos); if (attribute.IntervalTimeSpan < LowInterval) { CoreLog.Log(CoreLogLevel.Warning, $"Timer {method.DeclaringType}.{method.Name} has a low interval of {attribute.IntervalTimeSpan}."); } var timer = new TimerInfo { IsActive = true, Invoke = () => compiled(service, null, _serviceProvider, null), IntervalTicks = attribute.IntervalTimeSpan.Ticks, NextTick = tick + attribute.IntervalTimeSpan.Ticks }; _timers.Add(timer); } }
public void Create_IfReturnsTaskAndTaskCanceled_ReturnsCanceledTask(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "ReturnCanceledTask"); // Act IMethodInvoker <MethodInvokerFactoryTests> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests>(method); // Assert MethodInvokerFactoryTests instance = GetInstance(isInstance); Task task = invoker.InvokeAsync(instance, null); Assert.NotNull(task); task.WaitUntilCompleted(); Assert.Equal(TaskStatus.Canceled, task.Status); }
public void Create_IfParameterlessMethod_CanInvoke(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "ParameterlessMethod"); // Act IMethodInvoker <MethodInvokerFactoryTests> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests>(method); try { // Assert MethodInvokerFactoryTests instance = GetInstance(isInstance); invoker.InvokeAsync(instance, null).GetAwaiter().GetResult(); Assert.True(_parameterlessMethodCalled); } finally { _parameterlessMethodCalled = false; } }
private InvokerInfo CreateInvoker(MethodInfo method, MethodParameterSource[] parameterInfos, int callbackParamCount) { var compiled = MethodInvokerFactory.Compile(method, parameterInfos); return(new InvokerInfo { TargetType = method.DeclaringType, Invoke = (instance, eventContext) => { var args = eventContext.Arguments; if (callbackParamCount == args.Length) { return compiled(instance, args, eventContext.EventServices, _entityManager); } CoreLog.Log(CoreLogLevel.Error, $"Callback parameter count mismatch {callbackParamCount} != {args.Length}"); return null; } }); }
public void Create_IfMultipleReferenceParameters_RoundtripsArguments(bool isInstance) { // Arrange MethodInfo method = GetMethodInfo(isInstance, "TestByRefIntStringObjectArray"); int expectedInitialA = 1; string expectedInitialB = "B"; object[] expectedInitialC = new object[] { new object() }; int expectedFinalA = 2; string expectedFinalB = "b"; object[] expectedFinalC = new object[] { new object(), default(int), String.Empty }; // Act IMethodInvoker <MethodInvokerFactoryTests> invoker = MethodInvokerFactory.Create <MethodInvokerFactoryTests>(method); // Assert Assert.NotNull(invoker); bool callbackCalled = false; ByRefAction callback = delegate(ref int a, ref string b, ref object[] c) { callbackCalled = true; Assert.Equal(expectedInitialA, a); Assert.Same(expectedInitialB, b); Assert.Same(expectedInitialC, c); a = expectedFinalA; b = expectedFinalB; c = expectedFinalC; }; MethodInvokerFactoryTests instance = GetInstance(isInstance); object[] arguments = new object[] { expectedInitialA, expectedInitialB, expectedInitialC, callback }; invoker.InvokeAsync(instance, arguments).GetAwaiter().GetResult(); Assert.True(callbackCalled); Assert.Equal(expectedFinalA, arguments[0]); Assert.Same(expectedFinalB, arguments[1]); Assert.Same(expectedFinalC, arguments[2]); }
public void CreateTest() { MethodInvokerFactory target = new MethodInvokerFactory(); MethodInfo[] myMethodInfo; Type myType = typeof(MyClass); // Get the type and fields of FieldInfoClass. myMethodInfo = myType.GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); MethodInfo key = myMethodInfo[0]; IMethodInvoker actual; actual = target.Create(key); Assert.IsNotNull(actual); }
public void MethodInvokerFactoryConstructorTest() { MethodInvokerFactory target = new MethodInvokerFactory(); Assert.IsNotNull(target); }
private void CreateCommandsFromAssemblies(int prefixParameters) { var methods = ScanMethods(); foreach (var(method, commandInfo) in methods) { // Determine command name. var name = commandInfo.Name ?? GetCommandName(method); if (name == null) { continue; } // Validate acceptable return type. if (method.ReturnType != typeof(bool) && method.ReturnType != typeof(int) && method.ReturnType != typeof(void)) { continue; } var methodParameters = method.GetParameters(); // Determine command parameter types. if (!TryCollectParameters(methodParameters, prefixParameters, out var parameters)) { continue; } var info = new CommandInfo(name, parameters); var argsPtr = 0; // The current pointer in the event arguments array. var parameterSources = methodParameters .Select(inf => new MethodParameterSource(inf)) .ToArray(); // Determine the source of each parameter. for (var i = 0; i < parameterSources.Length; i++) { var source = parameterSources[i]; var type = source.Info.ParameterType; if (typeof(Component).IsAssignableFrom(type)) { // Components are provided by the entity in the arguments array of the event. source.ParameterIndex = argsPtr++; source.IsComponent = true; } else if (info.Parameters.FirstOrDefault(p => p.Index == i) != null) { // Default types are passed straight trough. source.ParameterIndex = argsPtr++; } else { // Other types are provided trough Dependency Injection. source.IsService = true; } } var data = new CommandData { Arguments = new object[info.Parameters.Length + prefixParameters], Info = info, Invoke = MethodInvokerFactory.Compile(method, parameterSources, false), SystemType = method.DeclaringType }; if (!_commands.TryGetValue(info.Name, out var lst)) { lst = _commands[info.Name] = new List <CommandData>(); } lst.Add(data); } }