Замок Виндзор и ИПринципал

Можно ввести IPrincipal с помощью Castle Windsor в мой контроллер asp.net mvc. В комментариях к этой статье, написанной Скоттом Хансельманом, есть код, позволяющий сделать это со структурной картой, но Я не могу понять, как это сделать с Каслом.

Обновлять:

Вот что у меня получилось для фабрики контроллеров. Обратите внимание, что большая часть кода взята из книги Стива Сандерсона Pro ASP.NET MVC с добавлением кода из ответов ниже.

public class WindsorControllerFactory : DefaultControllerFactory
{
    readonly WindsorContainer _container;
    // The constructor:
    // 1. Sets up a new IoC container
    // 2. Registers all components specified in web.config
    // 3. Registers IPrincipal
    // 4. Registers all controller types as components
    public WindsorControllerFactory()
    {
        // Instantiate a container, taking configuration from web.config
        _container = new WindsorContainer(
        new XmlInterpreter(new ConfigResource("castle"))
        );

        _container.AddFacility<FactorySupportFacility>();
        _container.Register(Component.For<IPrincipal>()
          .LifeStyle.PerWebRequest
          .UsingFactoryMethod(() => HttpContext.Current.User));

        // Also register all the controller types as transient
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        foreach (var t in controllerTypes)
            _container.AddComponentLifeStyle(t.FullName, t, LifestyleType.Transient);
    }

    // Constructs the controller instance needed to service each request
    protected override IController GetControllerInstance(Type controllerType)
    {
        return (IController)_container.Resolve(controllerType);
    }        
}

person beckelmw    schedule 03.07.2009    source источник
comment
Я бы не стал регистрировать объект и IPrincipal на фабрике контроллеров, они не связаны и должны быть отдельными.   -  person Mauricio Scheffer    schedule 07.10.2009


Ответы (2)


Если вы используете Windsor 2.0, изменять ControllerFactory не нужно:

var container = new WindsorContainer();
container.AddFacility<FactorySupportFacility>();
container.Register(Component.For<IPrincipal>()
  .LifeStyle.PerWebRequest
  .UsingFactoryMethod(() => HttpContext.Current.User));
// your component registrations...

Это просто оболочка конфигурации Factory. Если вы используете предыдущую версию (RC3), вы можете настроить это с помощью XML тоже.

person Mauricio Scheffer    schedule 04.07.2009
comment
О, классно. Не знал, что Windsor получил поддержку FactoryMethods. Но очевидно, что запрашивающий использует конфигурацию XML, поэтому AddComponentInstance будет работать независимо от версии. - person Tigraine; 04.07.2009
comment
Заводская поддержка существует уже давно, задолго до появления Fluent config API ... Я добавил ссылку на соответствующие документы. - person Mauricio Scheffer; 04.07.2009

Вы пытаетесь позволить Виндзору построить свой IPrincipal, где он должен просто использовать тот, который есть. Вставьте его в контейнер с помощью метода AddComponentInstance, предоставляемого MicroKernel в вашем ControllerFactory.

Очевидно, для этого потребуется собственный ControllerFactory, но он у вас уже должен быть.

Некоторое время назад я сделал нечто подобное для HttpContext: http://www.tigraine.at/2009/01/21/aspnet-mvc-hide-the-httpcontext-services-with-windsor-and-a-custom-controllerfactory/comment-page-1/#comment-2645

Ваша фабрика контроллеров может выглядеть так:

public IController CreateController(RequestContext requestContext, string controllerName)  
{  
    container.Kernel.AddComponentInstance<IPrincipal>(typeof (IPrincipal),  
                                                           System.Web.HttpContext.Current.User);  
    return (IController) container.Resolve(controllerName);  
}  

(Не забывайте, что ваши контроллеры должны быть для каждого веб-запроса или временными, иначе у вас возникнут проблемы)

person Tigraine    schedule 03.07.2009