2

Я пытаюсь перехватить вызовы методу Handle в моих обработчиках команд. этот процесс отлично работает, когда я явно регистрирую каждый обработчик команд, проблема в том, что моя общая регистрация обработчиков команд и перехватчика неверна.Захват windsor intercepter

исключение:

Исключение типа 'Castle.MicroKernel.ComponentActivator.ComponentActivatorException' произошло в Castle.Windsor.dll, но не был обработан в пользовательском коде

Дополнительная информация: ComponentActivator: не могли бы прокси TempSearch.Command.Data.CommandHandlers.AddTempsJobCommandHandler

Это выглядит как он не может найти Intercepter, как он говорит, что некоторые компоненты неправильно:.

«Некоторые зависимости от этого компонента не может быть статически решена \ г \ n'TempSearch.Command.Data.CommandHandlers.AddTempsCandidateAvailabilityCommandHandler» ждет следующих зависимостей: \ r \ n- Компонент 'TempSearch.Ioc.ExceptionHandlingIntercepter' (через переопределение), который был не найден. Забыли ли вы зарегистрировать его или опечатали имя? Если компонент зарегистрирован и переопределение с помощью типа убедитесь, что он не имеет имени не по умолчанию, назначенное явно или переопределить зависимости через имя \ г \ п»

Интерфейс:.

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

пример команды Handler:

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

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

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

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

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

Любые дополнительные данные из внутреннего исключения? –

+0

@phil, пожалуйста, см. Отредактированный вопрос, также отлично работает, когда я явно регистрирую каждый обработчик команд, проблема в том, что моя общая регистрация обработчиков команд и интерсептера неверна. – Xerxes

+0

Я думаю, что @samy прибил его –

ответ

3

Вы должны зарегистрировать сам перехватчик для того, чтобы позволить замок решить его при инициализации обработчиков команд. Добавьте следующий код вашей регистрации:

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

Я хотел назвать свои перехватчики, чтобы зарегистрировать их по имени (не знаю, почему, так как ваш путь должен работать нормально)

0

Я установил это, используя этот код:

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>()) 
       ); 
     } 
Смежные вопросы