代码之家  ›  专栏  ›  技术社区  ›  Daren Thomas

如何在具有特定名称的当前程序集中查找C接口的实现?

  •  6
  • Daren Thomas  · 技术社区  · 17 年前

    我有一个接口 IStep 可以做一些计算(见 Execution in the Kingdom of Nouns “”。在运行时,我希望按类名选择适当的实现。

    // use like this:
    IStep step = GetStep(sName);
    
    4 回复  |  直到 13 年前
        1
  •  8
  •   lubos hasko    17 年前

    你的问题很困惑…

    如果要查找实现ISTEP的类型,请执行以下操作:

    foreach (Type t in Assembly.GetCallingAssembly().GetTypes())
    {
      if (!typeof(IStep).IsAssignableFrom(t)) continue;
      Console.WriteLine(t.FullName + " implements " + typeof(IStep).FullName);
    }
    

    如果您已经知道所需类型的名称,只需执行此操作

    IStep step = (IStep)Activator.CreateInstance(Type.GetType("MyNamespace.MyType"));
    
        2
  •  2
  •   Ian Nelson    17 年前

    如果实现具有无参数的构造函数,则可以使用System.Activator类来实现。除了类名之外,还需要指定程序集名称:

    IStep step = System.Activator.CreateInstance(sAssemblyName, sClassName).Unwrap() as IStep;
    

    http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

        3
  •  1
  •   Daren Thomas    13 年前

    根据其他人所指出的,这就是我最后写的:

    /// 
    /// Some magic happens here: Find the correct action to take, by reflecting on types 
    /// subclassed from IStep with that name.
    /// 
    private IStep GetStep(string sName)
    {
        Assembly assembly = Assembly.GetAssembly(typeof (IStep));
    
        try
        {
            return (IStep) (from t in assembly.GetTypes()
                            where t.Name == sName && t.GetInterface("IStep") != null
                            select t
                            ).First().GetConstructor(new Type[] {}
                            ).Invoke(new object[] {});
        }
        catch (InvalidOperationException e)
        {
            throw new ArgumentException("Action not supported: " + sName, e);
        }
    }
    
        4
  •  0
  •   samjudson    17 年前

    好吧,assembly.createInstance似乎是一种可行的方法——唯一的问题是它需要类型的完全限定名,即包括名称空间。