gpt4 book ai didi

c# - CaSTLe Windsor - 注入(inject) IActionInvoker 实现问题

转载 作者:太空狗 更新时间:2023-10-30 00:34:48 27 4
gpt4 key购买 nike

我正在尝试使用 this 中的方法文章,但我遗漏了一些东西 - 我目前在 WindsorControllerFactory.GetControllerInstance 中遇到错误,因为它试图解析 IActionInvoker,因为 WindsorActionInvoker 依赖于 IWindsorContainer。

鉴于 WindsorControllerFactory 已经有对 IWindsorContainer 的引用,我可以传递该引用吗?如果是这样 - 怎么样?我发现的唯一示例是关于将值类型作为构造函数参数传递的,而不是引用类型。

我觉得我遗漏了一些明显的东西......

当前设置如下:在 Global.asax Application_Start 中,我调用了以下方法:

 protected virtual IWindsorContainer InitializeServiceLocator()
{
IWindsorContainer container = new WindsorContainer();
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));

container.RegisterControllers(typeof(HomeController).Assembly);
ComponentRegistrar.AddComponentsTo(container);

return container;
}

组件注册器:

 public static void AddComponentsTo(IWindsorContainer container) 
{
//add other components.....

container.AddComponentLifeStyle<IActionInvoker, WindsorActionInvoker>(LifestyleType.PerWebRequest);

}

WindsorActionInvoker:

public class WindsorActionInvoker : ControllerActionInvoker, IActionInvoker
{
readonly IWindsorContainer container;

public WindsorActionInvoker(IWindsorContainer container)
{
this.container = container;
}

protected override ActionExecutedContext InvokeActionMethodWithFilters(
ControllerContext controllerContext,
IList<IActionFilter> filters,
ActionDescriptor actionDescriptor,
IDictionary<string, object> parameters)
{
foreach (IActionFilter actionFilter in filters)
{
container.Kernel.InjectProperties(actionFilter);
}
return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);
}
}

温莎 Controller 工厂:

 public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer container;

public WindsorControllerFactory(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
this.container = container;
}

public override void ReleaseController(IController controller)
{
var disposable = controller as IDisposable;

if (disposable != null)
{
disposable.Dispose();
}

this.container.Release(controller);
}

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
return base.GetControllerInstance(requestContext, controllerType);
}

var controller = this.container.Resolve(controllerType) as Controller;

if (controller != null)
{
controller.ActionInvoker = this.container.Resolve<IActionInvoker>(this.container);
}

return controller;
}
}

Update

我错过了一个微妙之处:我试图将此行为用于以下目的:

public class CustomAuthorize : AuthorizeAttribute {...}

它没有实现 IActionFilter

向 WindsorActionInvoker 添加了以下内容:

 protected override AuthorizationContext InvokeAuthorizationFilters(ControllerContext controllerContext, IList<IAuthorizationFilter> filters, ActionDescriptor actionDescriptor)
{
foreach (IAuthorizationFilter authorizeFilter in filters)
{
this.kernel.InjectProperties(authorizeFilter);
}
return base.InvokeAuthorizationFilters(controllerContext, filters, actionDescriptor);
}

这现在可以按要求工作了。感谢 Cristiano,因为正是对他友善提供的代码的分析让我走上了正确的道路。

最佳答案

全局.asax

private static void bootstrapContainer()
{
container = new WindsorContainer()
.Install(FromAssembly.This());
var controllerFactory = new WindsorControllerFactory(container.Kernel);

ControllerBuilder.Current.SetControllerFactory(controllerFactory);
}

安装器/灌装容器

public class ControllersInstaller : IWindsorInstaller
{
#region IWindsorInstaller Members

public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<WpRegistration.Web.Filters.AgencyAuthorize>().LifeStyle.Transient);
container.Register(Component.For<IActionInvoker>().ImplementedBy<WindsorExtensions.Mvc.WindsorActionInvoker>().LifeStyle.Transient);

container.Register(AllTypes.FromThisAssembly()
.BasedOn<IController>()
.If(Component.IsInSameNamespaceAs<HomeController>())
.If(t => t.Name.EndsWith("Controller"))
.Configure((c => c.LifeStyle.Transient)));
}

#endregion
}

温莎 Controller 工厂

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

using Castle.MicroKernel;

public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IKernel kernel;

public WindsorControllerFactory(IKernel kernel)
{
this.kernel = kernel;
}

public override void ReleaseController(IController controller)
{
kernel.ReleaseComponent(controller);
}

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
}

IController iController = (IController)kernel.Resolve(controllerType);

// new code
if (iController is Controller)
{
((Controller)iController).ActionInvoker = kernel.Resolve<IActionInvoker>();
}

return iController;
}
}

温莎 Action 调用者

namespace WindsorExtensions.Mvc
{

public class WindsorActionInvoker : ControllerActionInvoker
{
readonly IKernel kernel;
public WindsorActionInvoker(IKernel kernel)
{
this.kernel = kernel;
}
protected override ActionExecutedContext InvokeActionMethodWithFilters(
ControllerContext controllerContext
, IList<IActionFilter> filters
, ActionDescriptor actionDescriptor
, IDictionary<string, object> parameters)
{
foreach (IActionFilter actionFilter in filters)
{
kernel.InjectProperties(actionFilter);
}
return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);
}
}

public static class WindsorExtension
{
public static void InjectProperties(this IKernel kernel, object target)
{
var type = target.GetType();
foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (property.CanWrite && kernel.HasComponent(property.PropertyType))
{
var value = kernel.Resolve(property.PropertyType);
try { property.SetValue(target, value, null); }
catch (Exception ex)
{
var message = string.Format("Error setting property {0} on type {1}, See inner exception for more information.", property.Name, type.FullName);
throw new ComponentActivatorException(message, ex);
}
}
}
}
}
}

机构授权属性

namespace WpRegistration.Web.Filters 
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class AgencyAuthorize : ActionFilterAttribute
{
CurrentUserService _currentUserSvc;
public AgencyAuthorize() { }

public CurrentUserService Service
{
get { return _currentUserSvc; }
set
{
this._currentUserSvc=value;
}
}

关于c# - CaSTLe Windsor - 注入(inject) IActionInvoker 实现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6622613/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com