简体   繁体   English

在构造函数中使用具有不同参数的反射调用类方法?

[英]Invoke Class Method using Reflection with different params in constructor?

Hello i am very new to c# reflection and i have the following problem. 您好,我是C#反射的新手,但我遇到以下问题。

I have a CommandDispatcher class that invokes a certain Command class that does something. 我有一个CommandDispatcher类,该类调用某个执行某些操作的Command类。

For now i use a switch to determinate what command to invoke. 现在,我使用开关来确定要调用的命令。

i wanted to simplify the code by using reflection to invoke the right command and get rid of the switch for good. 我想通过使用反射来调用正确的命令并永久删除开关来简化代码。

But each command takes a certain service or more in its constructor. 但是每个命令在其构造函数中都需要某种服务或更多服务。 I don't want to change that part . 我不想改变那部分。 I understand that if i had no services passed in the constructor the code would work fine. 我知道,如果我没有在构造函数中传递任何服务,则代码可以正常工作。

So how can i invoke my commands with reflection when each command takes one or many services. 因此,当每个命令接受一项或多项服务时,我该如何通过反射来调用我的命令。

Here is an image for better understanding: The code with color indicators 这是一个更好理解的图像: 带有颜色指示器的代码

I left the switch not commented out for easier reading. 我保留了开关的注释,以方便阅读。

Here is the code in pastebin: https://pastebin.com/AMQeh1zw 这是pastebin中的代码: https : //pastebin.com/AMQeh1zw

My search did not result in finding anything to solve my problem. 我的搜索没有找到解决我问题的任何方法。

The best way to handle your use case is to use IoC and DI. 处理用例的最佳方法是使用IoC和DI。

For the case of reflection as of now you can determine the constructor parameters and their types for a given type by using following code. 对于现在的反射情况,您可以使用以下代码确定给定类型的构造函数参数及其类型。

Let say there is a class MyClass 假设有一个类MyClass

public class MyClass
{
     int age;
     double salary;
     public MyClass(int x, double y)
     {
         age = x;
         salary = y;
     }
}

You can get information about all the constructors of MyClass using following logic 您可以使用以下逻辑获取有关MyClass所有构造函数的信息

var ctors = typeof(MyClass).GetConstructors();
// assuming class MyClass has only one constructor
var ctor = ctors[0];
foreach (var param in ctor.GetParameters())
{
    Console.WriteLine(string.Format(
        "Param {0} is named {1} and is of type {2}",
        param.Position, param.Name, param.ParameterType));
}

Now once you know the type of the constructor parameters you can create objects of those types with values assigned to them and use them to create object of MyClass as following. 现在,一旦知道了构造函数参数的类型,就可以创建具有分配给它们的值的那些类型的对象,并使用它们按如下方式创建MyClass对象。

var parameters = new List<object>();
foreach (var param in ctor.GetParameters())
{
    var obj = Activator.CreateInstance(param.ParameterType);
    parameters.Add(obj);
}

var myClassObj = Activator.CreateInstance(typeof(MyClass), parameters.ToArray());

The limitation here, you would notice, is you can not set properties or values of obj as it is of tyoe object . 您会注意到,这里的限制是您不能设置obj属性或值,因为它是tyoe object属性或值。 If you convert it to specific type then you will end up having switch case or if-else ladder. 如果将其转换为特定类型,则最终将遇到switch caseif-else梯形图。 So as long as the constructor of your class expects parameters of reference type (class type) this code would work fine. 因此,只要您的类的构造函数期望引用类型(类类型)的参数,此代码就可以正常工作。

I suggest to use Dependency Injection library for example Ninject and nuget link . 我建议使用Dependency Injection库,例如Ninjectnuget link For your purporse you can use next construction: 对于您的目的,您可以使用下一个结构:

This code init your Dependency Injection core 此代码初始化您的依赖注入核心

    var kernel = new StandardKernel();
    kernel.Load(Assembly.GetExecutingAssembly());

And your switch: 和你的开关:

switch (commandName)
        {
            case "RegisterUser":
                RegisterUserCommand registerUser = kernel.Get<RegisterUserCommand>();
                result = registerUser.Execute(commandParameters);
                break;
            case "Login":
                LoginCommand loginCommand = kernel.Get<LoginCommand>();
                result = loginCommand.Execute(commandParameters);
                break;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM