从String中检索类型

时间:2014-04-14 15:23:04

标签: c# generics types

我有这堂课:

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行的*符号的类型。 我用google搜索了araound,但没有运气。

3 个答案:

答案 0 :(得分:2)

您需要做的是按照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>();

答案 1 :(得分:0)

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

因此,如果命名空间已知,但未传入,则可以执行

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

但是,您不能将此Type对象作为类型参数传递,因为这不是泛型的工作原理。泛型需要在编译时知道类型 - 因此将Type对象作为Typeparameter传递并不是说这是必需类型的有效方式。

为了解决这个问题,可以使用这种反射。 dav_i还有另一个答案,它证明了这一点。

答案 2 :(得分:0)

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字符串。