是否可以使用Castle Windsor将IPrincipal注入我的asp.net mvc控制器。 Scott Hanselman的这篇文章在评论中有代码来处理结构图,但我无法弄清楚如何使用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);
}
}
答案 0 :(得分: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...
这只是Factory工厂配置的包装。如果您使用的是以前的版本(RC3),则可以configure this with XML too。
答案 1 :(得分: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);
}
(不要忘记您的控制器必须是针对此网络请求或暂时的,否则您将遇到麻烦)