Подтвердить что ты не робот

Замок Виндзорский резольвер для MVC 3

Поскольку реализация 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;
    }
4b9b3361

Ответ 1

Интерфейс не изменился со времени бета-версии, поэтому все реализации для различных фреймворков должны работать. И правда в том, что это не так сложно с интерфейсом... вы должны иметь возможность самостоятельно катиться без особых хлопот. Например, я сделал это для Ninject:

public class NinjectDependencyResolver : IDependencyResolver
{
    public NinjectDependencyResolver(IKernel kernel)
    {
        _kernel = kernel;
    }

    private readonly IKernel _kernel;

    public object GetService(Type serviceType)
    {
        return _kernel.TryGet(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _kernel.GetAll(serviceType);
    }
}

Затем подключите его в global.asax следующим образом:

    private static IKernel _kernel;
    public IKernel Kernel
    {
        get { return _kernel; }
    }

    public void Application_Start()
    {
        _kernel = new StandardKernel(new CoreInjectionModule());
        DependencyResolver.SetResolver(new NinjectDependencyResolver(Kernel));
        ...
    }

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

EDIT: Чтобы быть ясным, я не уверен, что ваши "активаторы", но вы, вероятно, им не нужны. Интерфейс IDependencyResolver обрабатывает новаторство контроллеров и представлений автоматически.

Ответ 2

Интерфейс MVC3 IDependencyResolver имеет большую проблему: нет метода выпуска. Это означает, что есть потенциальная утечка памяти, если вы собираетесь использовать ее с Виндзором. См. Мой блог о нем здесь:

http://mikehadlow.blogspot.com/2011/02/mvc-30-idependencyresolver-interface-is.html

Ответ 3

MVCContrib в настоящее время является авторитетным источником интеграции IoC-MVC. В настоящее время ветвь MVC3 включает только контроллеры factory и реализации IDependencyResolver (и еще пару вещей). Я рекомендую развернуть хранилище и внедрить недостающие точки расширения (не должен быть слишком сложным), а затем отправить команде запрос на перенос.