预加载程序集似乎不起作用

Pre-loading assembly doesn't seem to work

我正在编写一个测试来检查我的 Unity 配置中的所有控制器是否都已正确注册。作为测试的一部分,我使用反射来检查从 System.Web.Mvc.Controller 继承的所有非抽象 类。但是,我始终得到 System.Reflection.ReflectionTypeLoadException。我觉得这很奇怪,原因有二:

  1. 我的文件顶部有一个 using 语句,当测试 运行.
  2. 时,应该会导致此特定程序集自动加载
  3. 我还尝试预加载程序集。

我的代码是:

using System.Linq;
using System.Reflection;
using System.Text;
using System.Web.Mvc;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Unity;

namespace Presentation.Tests
{
    [TestClass]
    public class UnityTests
    {
        [TestMethod]
        public void UnityRegistration_ControllersInitialize()
        {
            // Initialize the container the same way we do in the code
            // but make sure that the container is disconnected from the application
            // so we don't accidentally change runtime behavior through testing
            var container = UnityRegistration.Initialize(new UnityContainer());

            // Get all the controllers in the presentation layer so we can check whether or not
            // they can all be constructed at runtime
            Assembly.Load("System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
            var assembly = Assembly.ReflectionOnlyLoad("Presentation, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
            var ctrls = assembly.GetTypes()
                .Where(t => t.IsAssignableFrom(typeof (Controller)) && !t.IsAbstract && t.IsClass);

            var builder = new StringBuilder();
            foreach (var ctrl in ctrls)
            {
                // Check resolution on each type. If resolution fails or
                // the result is null then we should record the error
                bool isErr;
                try
                {
                    var obj = container.Resolve(ctrl);
                    isErr = obj == null;
                }
                catch
                {
                    isErr = true;
                }

                if (isErr)
                {
                    builder.AppendLine(string.Format("Controller of type {0} could not be resolved.", ctrl.Name));
                }
            }

            string errors = builder.ToString();
            if (!string.IsNullOrWhiteSpace(errors))
            {
                Assert.Fail(errors);
            }
        }
    }
}

注意这里提到的Controller特指System.Web.Mvc.Controller.

抛出的异常没有内部异常和大量的loader异常,都说明了Cannot resolve dependency to assembly 'System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.

有人可以解释一下为什么预加载似乎无法以这种方式工作,以及我如何正确确保加载正确的程序集吗?

来自微软 Docs:

The reflection-only load context allows you to examine assemblies compiled for other platforms or for other versions of the .NET Framework. Code loaded into this context can only be examined; it cannot be executed. This means that objects cannot be created, because constructors cannot be executed. Because the code cannot be executed, dependencies are not automatically loaded. If you need to examine them, you must load them yourself.

在您的代码中:

var obj = container.Resolve(ctrl);

您不能使用 ctrl 类型做任何事情,除了检查它。您不能创建任何依赖于它的对象。