从字符串中检索类型

本文关键字:类型 检索 字符串 | 更新日期: 2023-09-27 17:58:27

我有这个类:

namespace Ns1.Ns2.Domain
{
    public class Process
    {
        private IIndex IndexBuilderConcr { get; set; }
        public Processo(String processType) {
            IndexBuilderConcr = new UnityContainer().RegisterType<IIndex, *>().Resolve<IIndex>();
        }
    }
}

这里我有一个构造函数,它接受一个String。此字符串表示一个类型,该类型应替换第8行的*号。我在谷歌上搜索了一遍,但运气不好。

从字符串中检索类型

您需要按照James S建议的方式获取类型,但您需要以稍微不同的方式将该值传递到方法中,因为调用Method<resolvedProcessType>无效:

var type = Type.GetType("Some.Name.Space." + processType);
var methodInfo = typeof(UnityContainer).GetMethod("RegisterType");
// this method's argument is params Type[] so just keep adding commas
// for each <,,,>
var method = methodInfo.MakeGenericMethod(IIndex, type);
// we supply null as the second argument because the method has no parameters
unityContainer = (UnityContainer)method.Invoke(unityContainer, null);
unityContainer.Resolve<IIndex>();

事实上,dav_i的答案非常正确,因为我使用Unity,实现这一点的最佳方法是命名映射:

namespace Ns1.Ns2.Domain
{
    public class Process
    {
        private IIndex IndexBuilderConcr { get; set; }
        public Processo(String processType) {
            IndexBuilderConcr = new UnityContainer().Resolve<IIndex>(processType);
        }
    }
}

然后在App.config:内部

<container>
  <register type="IIndex" mapTo="IndexAImpl" name="A"/>
  <register type="IIndex" mapTo="IndexBImpl" name="B"/>
</container>

其中name属性是processType字符串。

实现此操作的方法是静态Type.GetType(fullyQualifiedTypeNameString)。您需要知道实现此操作所需的命名空间,但如果程序集名称在当前执行的程序集中,则会推断程序集名称。

因此,如果名称空间是已知的,但没有传入,则可以执行

string fullyQualifiedTypeName = "MyNamespace." + processType;
Type resolvedProcessType = Type.GetType(fullyQualifiedTypeName);

但是,不能只将这个Type对象作为类型参数传递,因为泛型不是这样工作的。泛型要求类型在编译时是已知的,因此将type对象作为type参数传递并不是表示它是所需类型的有效方法。

为了避开这种反射,可以使用它。dav_i的另一个答案证明了这一点。