简体   繁体   English

从字符串中检索类型

[英]Retrieve type from a String

I have this class:我有这门课:

namespace Ns1.Ns2.Domain
{
    public class Process
    {
        private IIndex IndexBuilderConcr { get; set; }

        public Processo(String processType) {
            IndexBuilderConcr = new UnityContainer().RegisterType<IIndex, *>().Resolve<IIndex>();
        }
    }
}

Here I have a constructor that takes a String .在这里,我有一个接受String的构造函数。 This string represent a type that should replace the * sign at line 8. I have googled araound but with no luck.这个字符串代表一种应该替换第 8 行的 * 符号的类型。我用谷歌搜索了 araound 但没有运气。

What you'll need to do is get the type in the way James S suggests, but you'll need to pass that value into the method in a slightly different way as calling Method<resolvedProcessType> is invalid:您需要做的是按照 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>();

The method for this is the static Type.GetType(fullyQualifiedTypeNameString) You need to know the namespace for this to be possible, but the assembly name is inferred if it is in the currently executing assembly.这个方法是静态的Type.GetType(fullyQualifiedTypeNameString)你需要知道命名空间才能做到这一点,但如果它在当前执行的程序集中,则推断程序集名称。

So if the namespace is known, but not passed in you could do所以如果命名空间是已知的,但没有传入,你可以做

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

However you can't just pass this Type object as a typeparameter, because that's not how generics work.但是,您不能仅将此 Type 对象作为类型参数传递,因为这不是泛型的工作方式。 Generics require the type to be known at compile time - so passing a Type object as a Typeparameter is not a valid way of saying that is the required Type.泛型要求在编译时知道类型 - 因此将 Type 对象作为 Typeparameter 传递并不是说它是所需类型的有效方式。

To get round this reflection can be used instead.为了绕过这个反射,可以改用。 There is another answer by dav_i which demonstrates this. dav_i 的另一个答案证明了这一点。

The dav_i answer is pretty correct, indeed, since I'm using Unity the best way to achieve this is named mapping:事实上, 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);
        }
    }
}

and then inside the App.config :然后在App.config里面:

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

where name attributes is the processType string.其中name属性是processType字符串。

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

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