0

I'm trying to use reflection to automate a method repository.

For example I have a method.

public string CanCallThis(int moduleFunctionId)
{
    return "Hello";
}

Which I'm registory in my command manager like this.

commandManager.RegisterCommand(moduleName,"CanCallThis", new ModuleCommand<int, string>(CanCallThis));

This works fine, but it's a manual process to register each command.

I'm trying to use reflection so that I can probe the class for commands, then call the RegistrCommand method with the information discovered by reflection - this will make life much easier as I don't have to remember to add each RegisterCommand entry.

I'm in the process of creating the method that registers the method, currently my code looks like this.

List<MethodInfo> methodInfos = IdentifyMethods();

foreach (var methodInfo in methodInfos)
{
    ParameterInfo[] methodParams = methodInfo.GetParameters();

    if (methodParams.Length = 1)
    {
        Type returnType = methodInfo.ReturnType;
        string methodName = methodInfo.Name;
        Type inputParam = methodParams[0].ParameterType;

        commandManager.RegisterCommand(moduleName, methodInfo.Name, new ModuleCommand<inputParam, returnType>(unknown));
    }
}

In the above examples, inputParam, returnType and unknown are causing compliation errors. My goal here is to create an instance of ModuleCommand. I'm sure this is something to do with creating a delegate, but I'm not sure how to go about this.

Can someone help me create the ModuleCommand?

Colin Dawson
  • 435
  • 2
  • 12
  • 1
    possible duplicate of [How to use reflection to call generic Method?](http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method) – Stephen Jul 03 '15 at 11:08
  • I guess one of your compiler-errors comes from this: `methodParams.Length = 1` – MakePeaceGreatAgain Jul 03 '15 at 11:17
  • There is the [Delegate.CreateDelegate](https://msdn.microsoft.com/library/53cz7sc6.aspx) – xanatos Jul 03 '15 at 11:17
  • I wonder why you have generic delegates if you register and call them with reflection? You don't need compile time types in this case. It makes thing just more complicated. What about registering a `MethodInfo` directly? – Stefan Steinegger Jul 03 '15 at 11:25
  • Type genericType = typeof (ModuleCommand<,>).MakeGenericType(inputParam, returnType); IModuleCommand o = (IModuleCommand)Activator.CreateInstance(genericType, null); Gets me a step closer, but now I'm getting a problem calling Activator.CreateInstance as this requires that a parameter is passed to the constructor, the parameter is the method itself. – Colin Dawson Jul 03 '15 at 12:19
  • The problem with the answer to possible duplicate of How to use reflection to call generic Method? is that it does not have a parameter on the contructor. – Colin Dawson Jul 03 '15 at 12:22

1 Answers1

0

Found the solution, Here it is for everyone.

List<MethodInfo> methodInfos = IdentifyMethods();

foreach (var methodInfo in methodInfos)
{
    ParameterInfo[] methodParams = methodInfo.GetParameters();

    if (methodParams.Length == 1)
    {
        Type returnType = methodInfo.ReturnType;
        string methodName = methodInfo.Name;
        Type inputParam = methodParams[0].ParameterType;

        Type genericFuncType = typeof(Func<,>).MakeGenericType(inputParam, returnType);
        Delegate methodDelegate = Delegate.CreateDelegate(genericFuncType, this, methodInfo);

        Type genericModuleCommandType = typeof(ModuleCommand<,>).MakeGenericType(inputParam, returnType);

        IModuleCommand o = (IModuleCommand)Activator.CreateInstance(genericModuleCommandType, methodDelegate);

        commandManager.RegisterCommand(moduleName, methodName, o);
    }
}

The IModuleCommand in the code above is an interface that I created to that the ModuleCommand<,> implements. This is what has been implemented on the Registercommand method.

Colin Dawson
  • 435
  • 2
  • 12