【问题标题】:Castle Windsor and IPrincipal温莎城堡和 IPrincipal
【发布时间】:2009-07-03 21:34:06
【问题描述】:

可以使用 Castle Windsor 将 IPrincipal 注入到我的 asp.net mvc 控制器中。 Scott Hanselman 的这篇文章在 cmets 中有代码可以用结构图来做,但我不知道如何用 Castle 做。

更新:

这是我的控制器工厂的最终结果。请注意,大部分代码来自 Steve Sanderson 的 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);
    }        
}

【问题讨论】:

  • 我不会在控制器工厂中注册设施和 IPrincipal,它们不相关,应该分开。

标签: castle-windsor


【解决方案1】:

如果您使用的是 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...

这只是工厂设施配置的包装。如果您使用的是以前的版本 (RC3),您可以configure this with XML too

【讨论】:

  • 哦,太好了。不知道 Windsor 得到了 FactoryMethods 的支持。但是提问者显然是在使用 XML 配置,所以无论版本如何,AddComponentInstance 都可以工作。
  • 工厂支持已经存在很长时间了,远在 fluent 配置 API 之前...我添加了相关文档的链接。
【解决方案2】:

您尝试让 Windsor 构建您的 IPrincipal ,它必须只使用那里的那个。 通过你的 ControllerFactory 中 MicroKernel 暴露的 AddComponentInstance 方法将它注入到容器中。

这显然需要一个自定义的 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);  
}  

(不要忘记你的控制器必须是按网络请求或瞬态的,否则你会遇到麻烦)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多