【问题标题】:Unable to cast object of type XXXXXX to type IXXXXX (.NET 4.0)无法将 XXXXXX 类型的对象转换为 IXXXXX 类型(.NET 4.0)
【发布时间】:2013-02-25 22:10:03
【问题描述】:

谁能解释一下我发生了什么事?我有一个测试项目来测试我的服务的虚拟实例。在测试项目中,我简单引用了dummyService.exe和System.SystemProcess dll。

然而,在我的 dummyService 项目中,我引用了类库,它本身使用来自其他组件的其他 dll 以及我的解决方案中的其他项目。

问题是,当我运行我的测试时,抛出异常(在 dummyService 中加载和工作的 dll 的第一次机会异常),此外还有 invalidcast 异常(下面的错误消息)。

无法将“Export.CaseOutputGenerator”类型的对象转换为“Export.ICaseOutputGenerator”类型。 System.InvalidCastException 被捕获 消息=无法将类型为“Export.CaseOutputProcess.CustomCaseOutputGenerator”的对象转换为类型 'Export.CaseOutputProcess.ICaseOutputGenerator'。 Source=Export.CaseOutputProcess 堆栈跟踪: 在 Export.CaseOutputProcess.CaseOutputGeneratorFactory.GetCaseOutputGeneratorObject(String assemblyName, String className) 在 C:\Monitor\Export.CaseOutputProcess\CaseOutputGeneratorFactory.cs:56 行 在 Monitor.BOMock.GenerateCaseOutput(字符串 OutputFolder,字符串 iFile,Int32 seqNum,DataTable CaseSettings,字符串 SettingFileName) 在 C:\Monitor\BOMock\BOMock.cs:1069 行 在 C:\Monitor\BOMock\BOMock.cs:line 492 InnerException 中的 Monitor.BOMock.Handling():

     public static ICaseOutputGenerator GetCaseOutputGeneratorObject(string assemblyName, string className)
            {
                ICaseOutputGenerator customeOutputGen = null;

                var obj = GetObject(assemblyName, className);
                if (obj != null)
                    caseOutputGen = (ICaseOutputGenerator)obj; // FAILS HERE
                return caseOutputGen;
            }

   private static object GetObject(string fullName, string className)
        {
            try
            {
                Type caseOutputGen = null;
                var localAssembly = Assembly.LoadFrom(fullName);
                foreach (var testType in localAssembly.GetTypes())
                {
                    if (!testType.FullName.EndsWith(className, StringComparison.InvariantCultureIgnoreCase)) continue;
                    caseOutputGen = testType;
                    break;
                }
                if (caseOutputGen == null) return null;

                var obj = Activator.CreateInstance(caseOutputGen);
                return obj;
            }
            catch (FileNotFoundException ex)
            {
                throw new Exception("Failed to load assembly: " + Environment.NewLine + fullName, ex);
            }
            catch (Exception ex)
            {
                throw new Exception("Failed to load assembly: " + Environment.NewLine + fullName, ex);
            }
        }

其中 assemblyName 是要加载的 dll 文件的路径,而 className 恰好是要创建实例的类的名称。

在代码中,如您所见,我使用反射在提供的 assemblyName PATH 加载程序集 (String assemblyName) http://msdn.microsoft.com/en-us/library/system.reflection.assembly.loadfrom.aspx ,然后再次使用反射,然后创建包含在加载的程序集。 http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

请问我该如何解决这个问题?我不想在测试项目中引用我所有的 dll。请问我该如何解决或解决这个问题?提前致谢。

【问题讨论】:

  • 您是否研究过 Ninject 的依赖注入?
  • full 消息是什么?当您在两个不同的程序集中声明 ICaseOutputGenerator 时,通常会发生 - 在这种情况下,这是两个不同且不相关的 ICaseOutputGenerator 接口。
  • 这恰好是完整的消息。我不确定我应该在此发布哪些其他信息。请让我知道您究竟需要我发布什么。
  • CaseOutputGenerator 是否实现了ICaseOutputGenerator 接口?
  • 是的,它确实实现了它。

标签: c# .net visual-studio-2010 reflection


【解决方案1】:

根据该堆栈跟踪,似乎找不到该类型所在的程序集。如果您只是添加对已编译 exe 的引用,您可能不会获得其他库。我认为你有几个选择:

  1. 继续咬紧牙关:在您的测试项目中添加对其他库的引用。它们通常不具有传递性:仅仅因为您的服务知道它们并不一定意味着您的测试程序集也知道它们。
  2. 向您的测试项目添加一个编译后步骤,该步骤复制其他程序集,以便运行您的测试的应用程序域可以找到它们。
  3. 使用依赖注入和控制容器的反转。那里有很多,但会想到 Castle Windsor、StructureMap 和 Unity。 Scott Hanselman 在他的博客上有一个很棒的列表:http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx

【讨论】:

  • 在此之前,我一直在测试这些,非常成功,没有按照您的建议进行任何操作。我正在尝试测试服务,而测试是否没有意义,会让服务运行它的显示而不需要知道它内部发生的所有事情?
  • 可能。我认为这实际上取决于您的测试实际上在做什么,以及对服务可执行文件的引用是否将该可执行文件复制到您的测试程序集的文件夹中,而不是复制可执行文件的依赖项。
  • 看起来您正在使用模拟库。模拟库是否有可能在静态方面遇到问题?
  • 我使用反射在 assemblyName 路径 msdn.microsoft.com/en-us/library/… 加载程序集,然后再次使用反射,我创建了一个包含在加载程序集中的 className 实例。 msdn.microsoft.com/en-us/library/…
  • 谁能帮助我准确理解为什么在我的代码中使用反射现在需要我将反射程序集的引用添加到我的测试项目中?
猜你喜欢
  • 2021-08-27
  • 1970-01-01
  • 2021-12-06
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-19
  • 1970-01-01
相关资源
最近更新 更多