Я пишу тест, чтобы проверить, правильно ли зарегистрированы все контроллеры в моей конфигурации 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.
Может ли кто-нибудь объяснить, почему предварительная загрузка не работает таким образом, и как правильно обеспечить загрузку правильных сборок?
using
не вызовет загрузку сборки, которую вы должны использовать, иначе она будет оптимизирована. Вы можете зарегистрироватьAssemblyResolveEvent
и посмотреть, какие события он пытается разрешить. docs.microsoft.com/en-us/dotnet/api/ - person Rand Random   schedule 09.10.2018ReflectionTypeLoadException
, что такое исключения загрузчика и внутреннее исключение? - person JSteward   schedule 09.10.2018Assembly.ReflectionOnlyLoad
требуетсяFullName
изAssemlby
, а ваш вводPresentation
не похож наFullName
- docs.microsoft.com/en-us/dotnet/api/ - person Rand Random   schedule 09.10.2018Assembly.Load
с полным именем сборкиSystem.Web.Mvc
в качестве аргумента, который, как я понимаю, предварительно загружает ее. - person Woody1193   schedule 09.10.2018Assembly.ReflectionOnlyLoad
, я все еще могу получить информацию о сборке. Разве он не вернет null, если я не предоставлю достаточно информации для его загрузки? - person Woody1193   schedule 09.10.2018Controller
в сборкеSystem.Web.Mvc
. Это не считается его использованием? - person Woody1193   schedule 09.10.2018Presentation
, но это никак не повлияло на исключение. - person Woody1193   schedule 09.10.2018