Я пытаюсь использовать контейнер Unity, чтобы упростить unit test мои контроллеры. Мой контроллер использует конструктор, который принимает интерфейс к репозиторию. В файле global.asax я создаю экземпляр UnityContainerFactory и регистрирую его с помощью структуры MVC, а затем регистрирую репозиторий и его реализацию. Я добавил атрибут [Dependency] в параметр контроллера CTOR Repository. Кажется, что все это работает нормально, за исключением того, что время от времени factory GetControllerInstance (Type controllerType) вызывается более одного раза и передается пустой аргумент в качестве типа controllerType.
Первый вызов factory корректен, и в качестве аргумента передается тип контроллера ControlController. Но иногда, factory называется еще пару раз после того, как представление было отображено с нулевым значением для контроллера, и я не уверен, почему. Когда передается правильное значение типа контроллера, что "Call Stack" имеет смысл для меня, но когда передается значение null, я не уверен, почему или кто делает вызов. Любые идеи?
Ниже приведены коды и стеки вызовов для этого примера.
Вызов стека при работе
Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance(System.Type controllerType = {Name = "ProductsController" FullName = "Test.Controllers.ProductsController" }) Строка 23 С# Test.DLL! Test._Default.Page_Load (object sender = {ASP.default_aspx}, System.EventArgs e = {System.EventArgs}) Строка 18 + 0x1a байты С#
Вызов стека, когда NULL передается по типу controller
Test.DLL! Test.UnityHelpers.UnityControllerFactory.GetControllerInstance(System.Type controllerType = null) Строка 27 С#
Сначала я создал 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 для создания экземпляра контейнера factory
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;
}
}