拦截器不必每次都调用 Proceed
拦截器是实现日志记录或身份验证等跨领域问题的好工具。假设我们有以下服务:
public interface IService
{
string CreateOrder(NetworkCredential credentials, Order orderToCreate);
string DeleteOrder(NetworkCredential credentials, int orderId);
}
public class Service : IService
{
public string CreateOrder(NetworkCredential credentials, Order orderToCreate)
{
// ...
return "Order was created succesfully.";
}
public string DeleteOrder(NetworkCredential credentials, int orderId)
{
// ...
return "Order was deleted succesfully.";
}
}
我们可以创建以下拦截器:
public class AuthorizationInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
var userCredentials = invocation.Arguments[0] as NetworkCredential;
if (userCredentials.UserName == "tom" && userCredentials.Password == "pass123")
// this ^ verification is obviously silly, never do real security like this
{
invocation.Proceed();
}
else
{
invocation.ReturnValue = $"User '{userCredentials.UserName}' was not authenticated.";
}
}
}
这可以像这样注册和使用:
var container = new WindsorContainer();
container.Register(
Component.For<AuthorizationInterceptor>(),
Component.For<IService>().ImplementedBy<Service>().Interceptors<AuthorizationInterceptor>());
var service = container.Resolve<IService>();
System.Diagnostics.Debug.Assert(
service.DeleteOrder(new NetworkCredential { UserName = "paul", Password = "pass321" }, 8)
== "User 'paul' was not authenticated.");
System.Diagnostics.Debug.Assert(
service.CreateOrder(new NetworkCredential { UserName = "tom", Password = "pass123" }, new Order())
== "Order was created succesfully.");
重要的一课是拦截器可以决定传递调用,如果没有,它可以使用 ReturnValue
属性提供任意返回值。