Я пытаюсь использовать контейнер Unity, чтобы упростить модульное тестирование моих контроллеров. Мой контроллер использует конструктор, который принимает интерфейс к репозиторию. В файле global.asax я создаю экземпляр UnityContainerFactory и регистрирую его с помощью структуры MVC, а затем регистрирую репозиторий и его реализацию. Я добавил атрибут [Dependency] в параметр контроллера CTOR Repository. Все это работает нормально, за исключением того, что иногда GetControllerInstance (Type controllerType) фабрики вызывается более одного раза и передается пустым аргументом в качестве типа controllerType.ASP.NET MVC и Unity 1.2 Вопрос контейнера
Первый звонок на завод правилен, и контроллер «ProductsController» передается в качестве аргумента. Но иногда фабрика называется еще пару раз после того, как представление было отображено с нулевым значением для контроллера, и я не уверен, почему. Когда передается правильное значение типа контроллера, что «Call Stack» имеет смысл для меня, но когда передается значение null, я не уверен, почему или кто делает вызов. Есть идеи?
Ниже приведены коды и стеки вызовов для примера.
Стек вызовов при работает
test.dll! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (System.Type controllerType = {Name = "ProductsController" FullName = "Test.Controllers.ProductsController"}) Строка 23 C# test.dll! Test._Default.Page_Load (объект отправитель = {ASP.default_aspx}, System.EventArgs е = {System.EventArgs}) Строка 18 + 0x1a байт C#
Call Stack, когда NULL передается в controllerType
Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (Syst em.Type controllerType = нуль) Строка 27 C#
Сначала я создал UnityControllerFactory
public class UnityControllerFactory : DefaultControllerFactory
{
UnityContainer container;
public UnityControllerFactory(UnityContainer container)
{
this.container = container;
}
protected override IController GetControllerInstance(Type controllerType)
{
if (controllerType != null)
{
return container.Resolve(controllerType) as IController;
}
else
{
return null; // I never expect to get here, but I do sometimes, the callstack does not show the caller
}
}
}
Далее я добавил следующий код в файл global.asax для создания экземпляра контейнера автокрепеж
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
// Create Unity Container if needed
if (_container == null)
{
_container = new UnityContainer();
}
// Instantiate a new factory
IControllerFactory unityControllerFactory = new UnityControllerFactory(_container);
// Register it with the MVC framework
ControllerBuilder.Current.SetControllerFactory(unityControllerFactory);
// Register the SqlProductRepository
_container.RegisterType<IProductsRepository, SqlProductRepository>
(new ContainerControlledLifetimeManager());
}
Приложение имеет один контроллер
public class ProductsController : Controller
{
public IProductsRepository productsRepository;
public ProductsController([Dependency]IProductsRepository productsRepository)
{
this.productsRepository = productsRepository;
}
}
Вы на 100% уверены, что эта строка не возвращает null: return container.Resolve (controllerType) в качестве IController; Это кажется маловероятным, но этот приведение может легко вернуть значение null, если результирующий тип не был вызван IController или вызов Resolve. –
Привет Андерсон. Как вы можете видеть из стека вызовов, передается значение null. Я также остановился на линии, используя отладчик, и он был нулевым до начала трансляции. Этот вызов является единственной функцией в стеке в то время. Который я также не понимаю. Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance (System.Type controllerType = null) Строка 27 C# – Rick
Это то, что, как я думал, я видел в вашем стеке, но я хотел проверить свои предположения, чтобы убедиться. –