castle-windsor Interceptors Interceptors can have dependencies


Example

Interceptors are registered like regular components in Windsor. Like other components, they can depend on another components.

With following service for validating credentials:

public interface ICredentialsVerifier
{
    bool IsAuthorizedForService(NetworkCredential credentials);
}

public class MockCredentialsVerifier : ICredentialsVerifier
{
    public bool IsAuthorizedForService(NetworkCredential credentials)
        => credentials.UserName == "tom" && credentials.Password == "pass123";
        // this ^ verification is obviously silly, never do real security like this
}

We can use the following interceptor:

public class AuthorizationInterceptor : IInterceptor
{
    private readonly ICredentialsVerifier _credentialsVerifier;

    public AuthorizationInterceptor(ICredentialsVerifier credentialsVerifier)
    {
        _credentialsVerifier = credentialsVerifier;
    }

    public void Intercept(IInvocation invocation)
    {
        var userCredentials = invocation.Arguments[0] as NetworkCredential;

        if (_credentialsVerifier.IsAuthorizedForService(userCredentials))
        {
            invocation.Proceed();
        }
        else
        {
            invocation.ReturnValue = $"User '{userCredentials.UserName}' was not authenticated.";
        }
    }
}

We just have to properly register it in the composition root like this:

var container = new WindsorContainer();
container.Register(
    Component.For<AuthorizationInterceptor>(),

    Component.For<ICredentialsVerifier>().ImplementedBy<MockCredentialsVerifier>(),
    Component.For<IService>().ImplementedBy<Service>().Interceptors<AuthorizationInterceptor>());

var service = container.Resolve<IService>();