2009-07-03 171 views
2

是可能使用温莎城堡到我的asp.net mvc的控制器注入的IPrincipal。这篇由Scott Hanselman撰写的文章在注释中使用了结构映射的代码,但我无法弄清楚如何使用Castle来完成它。温莎城堡和IPrincipal的

更新:

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

我不会注册的控制器工厂内的设施和IPrincipal的,他们是不相关的,应该是分开的。 – 2009-10-07 15:28:29

回答

11

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

+1

很好。不知道温莎获得了对FactoryMethods的支持。 但提问者显然使用XML配置,所以无论Version如何,AddComponentInstance都可以工作。 – Tigraine 2009-07-04 11:53:57

2

你尽量让温莎构建你的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); 
} 

(不要忘记,你的控制器必须是每个web的请求或暂时的,否则你会遇到麻烦)