Контроллер MVC Общий впрыск с AutoFac - PullRequest
3 голосов
/ 18 января 2011

Я довольно новичок в DI с Autofac и задаюсь вопросом, возможно ли следующее

Я хочу создать общий контроллер и действие, которое получает впрыскиваемый тип. Я не хочу экземпляр внедренного типа, но просто нужно его тип, который будет дополнением ожидаемого интерфейса.

Я также хотел бы передать этот универсальный тип в ViewModel, но это совсем другая тема, однако, если кто-то из гениальных людей сможет решить и то, и другое, было бы отлично.

public ContractorController<T> : Controller 
    where T : IContractor{ 

    public ViewResult New() { 
            var vNewModel = new NewViewModel<T>(); 
            return View(vNewModel); 
        } 
} 

Этот контроллер должен вызываться через http://mysite.com/Contractor/New

Я пытался зарегистрировать дженерики в AutoFac, но это Кажется, что проблема в том, что AutofacControllerFactory реализует только GetControllerInstance (), ожидая, что тип контроллера, переданный ему из GetController () или CreateController (), не уверен, какая разница между ними. Эти методы получают имя контроллера в виде строки из RoutData и возвращают соответствующий тип .NET, который, давая URL, http://mysite.com/Contractor/New равен controller = Contractor, и, следовательно, ContractorController не может быть сопоставлен с помощью GetController () или CreateController () и, следовательно, передается ноль в GetControllerInstance (), означающий, что AutofacControllerFactory не пытается разрешить тип.

Я подумал, что мне придется создать собственную фабрику контроллеров. получая из AutofacControllerFactory, переопределить GetController () или CreateController () и выполнить мое собственное сопоставление имен контроллеров с общими типами. Что-то вроде

if (controllerName == "Исполнитель") return System.Type.GetType ( "UI.Controllers". + controllerName + "Controller`1");

Когда я отлаживаю это, я вижу, что этот код находит универсальный контроллер и возвращает его.

Я думал, что мог бы тогда просто зарегистрировать типы как

builder.RegisterType<FakeContractor>().As<IContractor>(); 
builder.RegisterGeneric(typeof(ContractorController<>)); 

Но я получаю следующую ошибку

The Autofac service 
'UI.Controllers.ContractorController`1' 
representing controller 
'ContractorManagement.UI.Controllers.ContractorController`1' 
in path '/Contractor/New' has not been registered. 

Так что я думаю, что я могу лаять не на то дерево. Может кто-нибудь, пожалуйста, пролить свет на то, как я могу сделать это, не потянув мои зубы

Спасибо

Ответы [ 2 ]

0 голосов
/ 20 января 2011

Возможно, это не прямой ответ на ваш вопрос, но это единственный возможный способ использовать универсальные контроллеры, которые я когда-либо видел и использовал:

public abstract class ContractorControllerBase<T> : Controller where T : IContractor { 
    public ViewResult New() { 
        var vNewModel = new NewViewModel<T>(); 
        return View(vNewModel); 
    } 
} 

public class FakeContractorController : ContractorControllerBase<FakeContractor> {
}
0 голосов
/ 19 января 2011

Я не совсем уверен, почему вы хотите контроллер, использующий универсальный.Использование универсального в контроллере не поддерживается в Mvc - или, по крайней мере, будет задействован поддерживающий путь маршрутизации.Возможно, вы можете предоставить больше информации о причинах этого подхода?

Как выглядит то, что вам нужен контроллер, который поддерживает привязку модели к различным типам.Следующий вопрос заключается в том, различаются ли эти типы в общем интерфейсе или базовом классе.

В этом случае для Mvc2 проверьте информацию IocModelBinder .Это будет работать с Autofac довольно хорошо.Это позволит типу быть привязанным к модели для публикации или получения, что позволит вам внедрять сервисы с помощью autofac.

Если вы хотите варьировать типы по общей базе - поддерживая различные модели конкретного вида - тогда посмотрите DerivedTypeModelBinder в MvcContrib .Существует версия, которая работает в Mvc 1, 2, и теперь в MvcContrib for Mvc3 есть хороший пример приложения для его сопровождения.Реализация Mvc3 также быстрее - скорость раньше не была проблемой, это просто более эффективный процесс идентификации.

...