Сборка с предварительной загрузкой не работает
Я пишу тест, чтобы проверить, что все контроллеры в моей конфигурации Unity зарегистрированы правильно. В рамках своего теста я использую рефлексию для проверки всех неабстрактных классов, которые наследуются от System.Web.Mvc.Controller
, Тем не менее, я последовательно получаю System.Reflection.ReflectionTypeLoadException
, Я нахожу это странным по двум причинам:
- В верхней части моего файла есть оператор using, который должен автоматически загружать эту сборку при запуске теста.
- Я также попытался предварительно загрузить сборку.
Мой код:
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
,
Возникшее исключение не имело внутреннего исключения и большого количества исключений загрузчика, которые все заявили 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.
Может кто-нибудь объяснить, почему предварительная загрузка, кажется, не работает таким образом, и как я бы правильно обеспечил загрузку соответствующих сборок?
1 ответ
Из документов Microsoft:
Контекст загрузки только для отражения позволяет вам исследовать сборки, скомпилированные для других платформ или для других версий.NET Framework. Код, загруженный в этот контекст, может быть только изучен; это не может быть выполнено. Это означает, что объекты не могут быть созданы, потому что конструкторы не могут быть выполнены. Поскольку код не может быть выполнен, зависимости не загружаются автоматически. Если вам нужно проверить их, вы должны загрузить их самостоятельно.
И в вашем коде:
var obj = container.Resolve(ctrl);
Вы не можете использовать ctrl
типа, чтобы сделать что-нибудь, кроме как просто исследовать это. Вы не можете создавать объекты, которые зависят от этого.