Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用Activator.CreateInstance()并支持多个构造函数签名_C#_Activator - Fatal编程技术网

C# 使用Activator.CreateInstance()并支持多个构造函数签名

C# 使用Activator.CreateInstance()并支持多个构造函数签名,c#,activator,C#,Activator,我需要实例化一个类型,该类型必须具有IConfiguration参数,但可能具有其他参数 目前我使用以下代码: Activator.CreateInstance(myType, BindingFlags.CreateInstance, null, new object[] { configuration }, CultureInfo.InvariantCulture); myType是要实例化的类型。这样编写,它需要一个构造函数,该构造函数正好有一个类型为IConfiguration的参数。如

我需要实例化一个类型,该类型必须具有
IConfiguration
参数,但可能具有其他参数

目前我使用以下代码:

Activator.CreateInstance(myType, BindingFlags.CreateInstance, null, new object[] { configuration }, CultureInfo.InvariantCulture);
myType
是要实例化的类型。这样编写,它需要一个构造函数,该构造函数正好有一个类型为
IConfiguration
的参数。如您所见,我通过对象数组传递
配置
对象以满足此要求

现在有一个新的要求:
myType
的构造函数可以有多个参数。其中一个必须接受
i配置
对象。在这部分代码中,其他参数可以忽略(或设置为默认值)。我怎样才能做到这一点

编辑:

这些是
myType
的可能类型。V1是当前需求,V2是新需求。这三个变量都是有效的,需要使用
配置
对象进行实例化

public class PluginV1
{
    private readonly IConfiguration configuration;

    public PluginV1(IConfiguration configuration)
    {
        this.configuration = configuration;
    }
}

public class PluginV2_A
{
    private readonly IConfiguration configuration;
    private readonly IExampleService exampleService;

    public PluginV2_A(IConfiguration configuration, IExampleService exampleService)
    {
        this.configuration = configuration;
        this.exampleService = exampleService;
    }
}

public class PluginV2_B
{
    private readonly IConfiguration configuration;
    private readonly IEnvironment environment;

    public PluginV2_B(IConfiguration configuration, IEnvironment environment)
    {
        this.configuration = configuration;
        this.environment = environment;
    }
}

也许我遗漏了一些东西,但您可以使用简单反射来获得正确的构造函数,以防有多个构造函数,并探索其输入参数

    public class Config : IConfiguration{}

    static void Main(string[] args)
    {
        var config = new Config();

        var o1  = Instantiate(typeof(PluginV1), config);
        var o2  = Instantiate(typeof(PluginV2_A), config);
        var o3  = Instantiate(typeof(PluginV2_B), config);
        Console.WriteLine(o1);
        Console.WriteLine(o2);
        Console.WriteLine(o3);
        Console.ReadKey();
    }

    private static object? Instantiate(Type type, IConfiguration config)
    {
        var targetConstructor =  type.GetConstructors().First();
        // in case there are several .ctors we can find suitable
        //        .First(info => info.GetParameters().Any(parameterInfo =>
        //            typeof(IConfiguration).IsAssignableFrom(parameterInfo.ParameterType)));
        var parameters = targetConstructor.GetParameters().Select(info =>
        {
            if (!typeof(IConfiguration).IsAssignableFrom(info.ParameterType))
            {
                return GetDefault(info.ParameterType);
            }

            return config;
        }).ToArray();
        var instance = Activator.CreateInstance(type, parameters);
        return instance;
    }

    // getting default values https://stackoverflow.com/a/353073/517446
    public static object GetDefault(Type type)
    {
        if(type.IsValueType)
        {
            return Activator.CreateInstance(type);
        }
        return null;
    }

也许我遗漏了一些东西,但您可以使用简单反射来获得正确的构造函数,以防有多个构造函数,并探索其输入参数

    public class Config : IConfiguration{}

    static void Main(string[] args)
    {
        var config = new Config();

        var o1  = Instantiate(typeof(PluginV1), config);
        var o2  = Instantiate(typeof(PluginV2_A), config);
        var o3  = Instantiate(typeof(PluginV2_B), config);
        Console.WriteLine(o1);
        Console.WriteLine(o2);
        Console.WriteLine(o3);
        Console.ReadKey();
    }

    private static object? Instantiate(Type type, IConfiguration config)
    {
        var targetConstructor =  type.GetConstructors().First();
        // in case there are several .ctors we can find suitable
        //        .First(info => info.GetParameters().Any(parameterInfo =>
        //            typeof(IConfiguration).IsAssignableFrom(parameterInfo.ParameterType)));
        var parameters = targetConstructor.GetParameters().Select(info =>
        {
            if (!typeof(IConfiguration).IsAssignableFrom(info.ParameterType))
            {
                return GetDefault(info.ParameterType);
            }

            return config;
        }).ToArray();
        var instance = Activator.CreateInstance(type, parameters);
        return instance;
    }

    // getting default values https://stackoverflow.com/a/353073/517446
    public static object GetDefault(Type type)
    {
        if(type.IsValueType)
        {
            return Activator.CreateInstance(type);
        }
        return null;
    }

我认为我们需要看到更多的代码。向我们展示至少部分旧构造函数和新构造函数重载。问题是如何完成构造函数选择?前面的评论不正确。您不能忽略其他参数,也不能假设它们将获得默认值。默认值是由编译器提供的,但如果它不知道您调用的构造函数是什么,则无法工作。您必须将它们添加到object[]数组中。我为
myType
添加了一些可能的类型,为什么需要使用activator来创建这些对象?为什么不正常地实例化它们?@Marie,因为编译时不知道类型。我想我们需要看到更多的代码。向我们展示至少部分旧构造函数和新构造函数重载。问题是如何完成构造函数选择?前面的评论不正确。您不能忽略其他参数,也不能假设它们将获得默认值。默认值是由编译器提供的,但如果它不知道您调用的构造函数是什么,则无法工作。您必须将它们添加到object[]数组中。我为
myType
添加了一些可能的类型,为什么需要使用activator来创建这些对象?为什么不正常地实例化它们?@Marie,因为编译时不知道类型。