Поскольку реализация IoC/DI в MVC 3, скорее всего, в окончательной форме в RC, я ищу обновленную реализацию DependencyResolver, IControllerActivator и IViewPageActivator с помощью Caste Windsor. Существуют ли какие-либо примеры, которые были обновлены для MVC 3 RC?
РЕДАКТИРОВАТЬ № 1 Реализация резольвера зависимостей Windsor действительно тривиальна, но все еще чего-то не хватает. В отличие от примера Джеффа Путца (ниже), кажется, что это не так просто, как с Виндзором. После настройки разрешения зависимостей, таким образом,
DependencyResolver.SetResolver(new WindsorDependencyResolver(container));
Windsor выбрасывает ComponentNotFoundException. Мне нужно предоставить реализацию для IControllerFactory и IControllerActivator. Так как DefaultControllerFactory является зависимым от Релевантности, это можно решить следующим образом:
Component.For<IControllerFactory >().ImplementedBy<DefaultControllerFactory>()
Component.For<IControllerActivator >().ImplementedBy<WindsorControllerActivator>(),
WindsorControllerActivator также является тривиальным. Однако это приводит к другому исключению ComponentNotFoundException для IViewPageActivator.
Это заставляет меня думать, что я чего-то не хватает. Невозможно, чтобы это было сложнее, чем реализация контроллера factory и вызов класса ControllerBuilder.Current.SetControllerFactory MVC 2.0.
РЕДАКТИРОВАТЬ # 2 Я пропустил тонкие, но важные детали, чтобы разрешающая способность Dependency возвращала значение null, когда не удалось найти службу. Реализация выглядит следующим образом:
public class WindsorDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer container;
public WindsorDependencyResolver(IWindsorContainer container)
{
this.container = container;
}
public object GetService(Type serviceType)
{
return container.Kernel.HasComponent(serviceType) ? container.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return container.Kernel.HasComponent(serviceType) ? container.ResolveAll(serviceType).Cast<object>() : new object[]{};
}
}
РЕДАКТИРОВАТЬ № 3
Отвечая на вопрос в комментариях. Если вы обнаружите, что вам нужен собственный IControllerActivator, вот простая реализация для Windsor:
public class WindsorControllerActivator : IControllerActivator
{
private readonly IWindsorContainer container;
public WindsorControllerActivator(IWindsorContainer container)
{
this.container = container;
}
public IController Create(RequestContext requestContext, Type controllerType)
{
return (IController)container.GetService(controllerType);
}
}
}
Опять же, это НЕ, чтобы получить базовый DI, работающий с Windsor и зависимым от MVC3.
РЕДАКТИРОВАТЬ # 4 Основываясь на некоторых дальнейших исследованиях и отзывах, кажется, что традиционная реализация контроллера factory - лучший подход для Windsor и MVC3. Вызывает беспокойство то, что интерфейс IDependencyResolver не имеет метода выпуска, который может вызвать утечку памяти, когда Windsor не будет утилизировать свои компоненты. Это, вероятно, не будет проблемой, если все ваши зависимости будут решены с помощью жизненного цикла PerWebRequest, но все же лучше не рисковать. Вот базовая реализация контроллера Windsor factory для MVC3.
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer container;
public WindsorControllerFactory(IWindsorContainer container)
{
this.container = container;
}
public override void ReleaseController(IController controller)
{
container.Kernel.ReleaseComponent(controller);
}
public override IController CreateController(RequestContext requestContext, string controllerName)
{
var controllerComponentName = controllerName + "Controller";
return container.Kernel.Resolve<IController>(controllerComponentName);
}
}
РЕДАКТИРОВАТЬ № 5 Если вы используете области MVC, описанная выше реализация не будет работать для вас. Вам необходимо будет зарегистрировать каждый контроллер на основе его полного имени и переопределить GetControllerInstance вместо CreateController:
protected override IController GetControllerInstance(RequestContext context, Type controllerType)
{
if (controllerType != null)
{
return (IController)container.Kernel.Resolve(controllerType);
}
return null;
}