Castle windsor intercepter

廉价感情. 提交于 2019-12-04 04:06:04

问题


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);
        }
    }
}

回答1:


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)




回答2:


I fixed this using this code:

public void Install(IWindsorContainer container, IConfigurationStore store)
        {    
            container.Register(
                Component.For<IInterceptor>()
                    .ImplementedBy<ExceptionHandlingIntercepter>().LifestyleTransient(),
                Classes
                    .FromAssemblyContaining<EcruiterCommands>()
                    .Where(t => t.Name.EndsWith("CommandHandler"))
                    .WithServiceAllInterfaces()
                    .LifestylePerWebRequest().Configure(c => c.Interceptors<ExceptionHandlingIntercepter>())
                );
        }


来源:https://stackoverflow.com/questions/29629645/castle-windsor-intercepter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!