Шесть лет спустя, с MVC5 (и MVC6) в городе, я столкнулся с той же проблемой. Я строю свой сайт с помощью MVC5, поэтому я могу с уверенностью предположить, что он еще не поддерживается "из коробки". Я приземлился здесь в поисках решения. Ну, в конце концов я нашел способ исправить это без взлома контроллера или его фабрики, особенно потому, что мне нужна была эта функция только в нескольких местах.
Подход: слегка изменить шаблон команды (который я уже использовал в своем коде в любом случае).
Для этой проблемы вы начинаете с определения интерфейса
public interface IMyActionProcessor
{
PartialViewResult Process<T>(T theModel);
}
и соответствующая реализация:
public sealed class MyActionProcessor : IMyActionProcessor
{
// Your IoC container. I had it explicitly mapped just like any other
// registration to cause constructor injection. Using SimpleInjector, it will be
// <code>Container.Register(typeof(IServiceProvider), () => Container);</code>
private IServiceProvider _serviceProvider;
public MyActionProcessor(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public PartialViewResult Process<T>(T theModel)
{
var handlerType =
typeof(IMyActionHandler<>).MakeGenericType(theModel.GetType());
dynamic handler = _serviceProvider.GetService(handlerType);
return handler.Handle((dynamic)theModel);
}
}
Обработчик (userd в коде выше) будет выглядеть так:
public interface IMyActionHandler<T> where T : class
{
PartialViewResult Execute(T theModel);
}
С учетом вышесказанного все, что вам теперь нужно сделать, это предоставить реализацию (ы) для обработчика на основе специфики вашего класса T
. Примерно так:
public class ModelClassHandler : IMyActionHandler<ModelClass>
{
public PartialViewResult Execute(ModelClass theModel);
{
// Do Stuff here and return a PartialViewResult instance
}
}
Имея все вышеперечисленное, вы можете просто сделать это в своем контроллере:
var processor = YourServiceLocator.GetService<IMyActionProcessor>();
var model = new ModelClass { /* Supply parameters */ };
var partialViewResult = processor.Process(model);
Я знаю, что это дополнительный уровень косвенности, но он работал превосходно. В моем случае я продолжил расширять обработчик и процессор, чтобы они могли возвращать все, что я хочу, а не только PartialViewResult
.
Мне будет интересно увидеть более простое решение, если таковое существует. Я полагаю, что такого рода проблемы не связаны с использованием MVC.
PS: Любой хороший контейнер IoC должен иметь возможность регистрировать открытые генерики путем сканирования сборок. Таким образом, после соответствующей настройки вам не нужно явно регистрировать реализации для интерфейса обработчика.
PPS: Этот пост дает более полное представление об ответе, приведенном здесь , особенно о том, как можно обобщить решение.