【问题标题】:Type.GetType(string typeName) returns nullType.GetType(string typeName) 返回 null
【发布时间】:2011-11-18 10:52:03
【问题描述】:

我的代码是

type = Type.GetType(key);

我传递的键是命名空间限定名。

我的代码在 BusinessLayer 中。我正在创建 DataAccessLayer 的一个实例。 DataAccessLayer 引用已添加到 BusinessLayer。

我收到的错误是 “无法从程序集 'BusinessLayer, Version=1.9.3.0, Culture=neutral, PublicKeyToken=null' 加载类型 'Catalyst.DAL.ExamDAO.CExamDAO'。”.

我应该怎么做才能明确指定该类来自 DataAccessLayer ?

键值是“Catalyst.DAL.ExamDAO.CExamDAO”

编辑:

我的实际代码是

public static object getClassInstance(string key, params  object[] constructorArgs)
        {
            string assemblyPath = null;
            string customClassName = null;
            DataSet objDataset = getAssemblyInfo(key);
            if (objDataset != null && objDataset.Tables.Count > 0 && objDataset.Tables[0].Rows.Count > 0)
            {
                assemblyPath = objDataset.Tables[0].Rows[0]["ACA_ASSEMBLY_PATH"].ToString();
                customClassName = objDataset.Tables[0].Rows[0]["ACA_CLASS_NAME"].ToString();
            }

            Assembly assembly;
            Type type;

            if (assemblyPath != null && assemblyPath != string.Empty)
            {
                assembly = Assembly.LoadFile(assemblyPath);
                type = assembly.GetType(customClassName);
            }
            else // if no customisation
            {
                type = Type.GetType(key);
            }

            object classInstance = constructorArgs == null ? Activator.CreateInstance(type) : Activator.CreateInstance(type, constructorArgs);
            if (classInstance == null) throw new Exception("broke");
            return classInstance;

        }

如果没有自定义,我正在尝试加载默认类。方法在 BO 中。 如果我将密钥作为任何 Bo 类型的命名空间限定名称传递,它将转换。但是DAO类型它不会

【问题讨论】:

  • 你为什么这样做而不是new CExamDAO()?如果确实“将 DataAccessLayer 引用添加到 BusinessLayer”,那么您应该没有理由不能使用 new 运算符。或者,如果您真的只是想要一个类型引用,那么 typeof(CExamDAO)
  • 给我们“key”的文本值。
  • @亚当拉尔夫。实际上我需要在自定义程序集和默认程序集之间切换。我尽力把代码放在这里。
  • @xanatos 我放了键值

标签: c# class reflection activator gettype


【解决方案1】:

或者试试这个:

 private static object GetResultFromStaticMethodClass(string qualifiedClassName, string method)
 {
      Type StaticClass = Type.GetType(qualifiedClassName);
      MethodInfo methodInfo = StaticClass.GetMethod(method);
      object result = methodInfo.Invoke(null, null);
      return result;
 }

用途:

object result = GetResultFromStaticMethodClass(
    "Utilities.StringHelper,DaProject",
    "ToList"
);

这会调用 StringHelper 类、Utilities 命名空间、DaProject 中的静态方法 ToList项目(相同的程序集和项目名称)。

如果需要参数,在methodInfo.Invoke(null, null)调用的第二个参数中添加

【讨论】:

    【解决方案2】:

    你的类型是公开的吗? 内部类不能从不同的程序集中加载。

    【讨论】:

      【解决方案3】:

      如果调用程序集中不存在该类型,则需要使用AssemblyQualifiedName 来获取它的类型实例。要解决您的问题,您需要将 key 值设置为 AssemblyQualifiedName 而不是 namespace qualified name

      【讨论】:

      • 这是很重要的一点,所选答案中没有提到:如果指定的类型不是来自调用程序集,则需要使用程序集限定名称。仅使用程序集名称是不够的。
      【解决方案4】:

      如果CExamDAOExamDao 的子类,则表示法是(注意+):

      Catalyst.DAL.ExamDAO+CExamDAO
      

      您可以做的最好的事情是直接创建一个 CExamDAO,然后获取它的GetType().AssemblyQualifiedName(例如在调试器中)。比如:

      (new CExamDAO()).GetType().AssemblyQualifiedName
      

      或者(如果你确定你需要它的地方已经加载了它的程序集)

      (new CExamDAO()).GetType().FullName
      

      然后将其复制/粘贴到您的代码中。

      【讨论】:

        【解决方案5】:

        如果您知道它属于DataAccessLayer 中的任何类型,那么我会尽可能简单地获得Assembly 引用,例如

         Assembly assembly = typeof(AnyPublicTypeWithinTargetAssembly).Assembly;
         Type type = assembly.GetType(namespaceQualifiedTypeName);
        

        另一种方法是使用带有程序集限定名称的Type.GetType,但这在指定类型名称方面更加冗长。

        【讨论】:

        • 什么是 AnyPublicTypeWithinTargetAssembly ,我无法访问这个。我需要使用哪个程序集参考。
        • AnyPublicTypeWithinTargetAssembly 是任何带有目标程序集的公共类型。只需在该程序集中选择一种您以后不会删除的类型,然后将其放入表达式中。此外,如果您知道程序集的名称,您可以使用 Assembly.LoadFrom(assemblyName)
        猜你喜欢
        • 1970-01-01
        • 2019-11-09
        • 2012-02-01
        • 2011-11-09
        • 1970-01-01
        • 2012-10-14
        • 1970-01-01
        相关资源
        最近更新 更多