城堡温莎截击 [英] Castle windsor intercepter

查看:261
本文介绍了城堡温莎截击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想拦截我的命令处理程序调用handle方法。
这个过程中正常工作时,我明确地注册的每个命令处理程序,问题是,我的命令处理程序和拦截器的通用注册是不正确的。



例外




输入
'Castle.MicroKernel.ComponentActivator.ComponentActivatorException'
发生在Castle.Windsor的异常。 DLL但在用户代码中没有处理



更多信息:ComponentActivator:不能代理
TempSearch.Command.Data.CommandHandlers.AddTempsJobCommandHandler




看起来它找不到截击,因为它说,
部分组件配置错误:




这个组件不能静态地的一些依赖
resolved.\r\\\
'TempSearch.Command.Data.CommandHandlers.AddTempsCandidateAvailabilityCommandHandler'
正在等待以下依赖性:\r\\\
-组件
'TempSearch.Ioc.ExceptionHandlingIntercepter'(通过覆盖)这是
未找到。你忘了注册,或拼错了名字?如果
组件被注册,倍率为通过型确保它
没有非默认的名称明确指定或通过name.\r\\\
覆盖
依赖




接口:

 公开接口ICommandHandler< TCommand> 
{
无效手柄(TCommand命令);
}

为例命令处理程序:

 公共类AddTempsCandidateAvailabilityCommandHandler 
:ICommandHandler< TempsCandidateAvailability>
{
私人只读的IDbConnection连接;

公共AddTempsCandidateAvailabilityCommandHandler(
的IDbConnection连接)
{
this.connection =连接;
}

公共无效手柄(TempsCandidateAvailability命令)
{
// ...
}
}

设好注册:

 公共无效安装(IWindsorContainer容器, IConfigurationStore店)
{
container.Register(
Component.For<&的IDbConnection GT;()
.UsingFactoryMethod(()=> ConnectionHelper.GetOpenDbConnection(
Connection.DatabaseName.ReedOnline))
.LifestylePerWebRequest());

container.Register(

.FromAssemblyContaining< EcruiterCommands>()
。凡(T => t.Name.EndsWith(命令))
.WithService
.AllInterfaces()LifestylePerWebRequest());

container.Register(

.FromAssemblyContaining< EcruiterCommands>()
。凡(T => t.Name.EndsWith(CommandHandler))
.WithService.AllInterfaces()
.LifestylePerWebRequest()
.Configure(C => c.Interceptors< ExceptionHandlingIntercepter>()
.LifestyleTransient()));
}



截击:

  [瞬态] 
公共类ExceptionHandlingIntercepter:IInterceptor
{
私人静态只读MethodInfo的执行=
的typeof(ICommandHandler<>)。实现getMethod(处理);

私人只读的iKernel内核;

公共ExceptionHandlingIntercepter(内核的iKernel)
{
this.kernel =内核;
}

公共无效拦截(IInvocation调用)
{
如果(invocation.Method!=执行)
{
invocation.Proceed ();
的回报;
}


{
invocation.Proceed();
}
终于
{
kernel.ReleaseComponent(invocation.Proxy);
}
}
}


解决方案

您必须注册拦截器为了让您的初始化命令处理程序时,城堡的解决。以下内容添加到您的注册:

  container.Register(
Component.For< ExceptionHandlingIntercepter>(); //应该足够

我喜欢我的命名被拦截的名字注册(不知道为什么,因为用自己的方式应该正常工作)


I am trying to intercept calls to the Handle method on my command handlers. this process works fine when I explicitly register each command handler, the problem is that my generic registration of the command handlers and the interceptor is not correct.

exception:

An exception of type 'Castle.MicroKernel.ComponentActivator.ComponentActivatorException' occurred in Castle.Windsor.dll but was not handled in user code

Additional information: ComponentActivator: could not proxy TempSearch.Command.Data.CommandHandlers.AddTempsJobCommandHandler

It looks like it cannot find the intercepter as it says that some components are misconfigured:

"Some dependencies of this component could not be statically resolved.\r\n'TempSearch.Command.Data.CommandHandlers.AddTempsCandidateAvailabilityCommandHandler' is waiting for the following dependencies:\r\n- Component 'TempSearch.Ioc.ExceptionHandlingIntercepter' (via override) which was not found. Did you forget to register it or misspelled the name? If the component is registered and override is via type make sure it doesn't have non-default name assigned explicitly or override the dependency via name.\r\n"

The interface:

public interface ICommandHandler<TCommand>
{
    void Handle(TCommand command);
}

an example Command Handler:

public class AddTempsCandidateAvailabilityCommandHandler 
    : ICommandHandler<TempsCandidateAvailability>
{
    private readonly IDbConnection connection;

    public AddTempsCandidateAvailabilityCommandHandler(
        IDbConnection connection)
    {
        this.connection = connection;
    }

    public void Handle(TempsCandidateAvailability command)
    {
        // ...
    }
}

the registeration:

public void Install(IWindsorContainer container, IConfigurationStore store)
{
    container.Register(
        Component.For<IDbConnection>()
            .UsingFactoryMethod(() => ConnectionHelper.GetOpenDbConnection(
                Connection.DatabaseName.ReedOnline))
            .LifestylePerWebRequest());

    container.Register(
        Classes
            .FromAssemblyContaining<EcruiterCommands>()
            .Where(t => t.Name.EndsWith("Commands"))
            .WithService
            .AllInterfaces().LifestylePerWebRequest());

    container.Register(
        Classes
            .FromAssemblyContaining<EcruiterCommands>()
            .Where(t => t.Name.EndsWith("CommandHandler"))
            .WithService.AllInterfaces()
            .LifestylePerWebRequest()
            .Configure(c => c.Interceptors<ExceptionHandlingIntercepter>()
                .LifestyleTransient()));
}

the intercepter:

[Transient]
public class ExceptionHandlingIntercepter : IInterceptor
{
    private static readonly MethodInfo Execute = 
        typeof(ICommandHandler<>).GetMethod("Handle");

    private readonly IKernel kernel;

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

    public void Intercept(IInvocation invocation)
    {
        if (invocation.Method != Execute)
        {
            invocation.Proceed();
            return;
        }

        try
        {
            invocation.Proceed();
        }
        finally
        {
            kernel.ReleaseComponent(invocation.Proxy);
        }
    }
}

解决方案

You must register the interceptor itself in order to let Castle resolve it when initializing your command handlers. Add the following to your registration:

container.Register(
    Component.For<ExceptionHandlingIntercepter>(); // should be enough

I like naming my interceptors to register them by name (don't know why, since your way should work fine)

这篇关于城堡温莎截击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆