使用 Castle Windsor 构建应用程序

Architecting applications with Castle Windsor

我目前正在尝试使用 Castle 实现 AOP。我创建了一个 .NET 解决方案来处理业务(我们将其命名为项目 1)。我正在考虑创建一个单独的项目来容纳我所有与 AOP 相关的 类(方面)(这被命名为项目 2)。我的问题是:

1) 是否可以在项目 1 中使用 xml 配置文件来配置在运行时应用哪些方面? (我很清楚这种可能性,但如果不是这样请告诉我)

2) 是否可以不触及项目 1(代码 change/rebuilding)以添加新方面/删除旧方面,并让所有这些都通过项目 2 进行管理?换句话说,我不想 change/build 我的业务解决方案,因为将来会增加或删除方面。

可以用XML(https://github.com/castleproject/Windsor/blob/master/docs/registering-components.md)配置组件,不需要rebuild,project 2也可以配置AOP,可以让project 1调用项目 2 注册 IOC 服务,从这一点开始,您可以注册拦截器作为方面并将它们应用于您希望的任何组件,项目 2 需要引用项目 1 或包含您希望的接口和实现的项目注册这些。

示例:

container.Register(
   Component.For<LoggingInterceptor>().Lifestyle.Transient,
   Component.For<CacheInterceptor>().Lifestyle.Transient,
   Component.For<IOrderRepository>().ImplementedBy<OrderRepository>());

您不必更改业务代码,您可以正交地注册拦截器,在项目 2 中,您将引用业务项目并针对该接口注册任何自定义拦截器。您可以完全避免 xml 配置并在项目 2 中进行配置,您将重建项目 2 并将其放入,然后重新启动应用程序。你也可以用 xml 注册拦截器 (https://github.com/castleproject/Windsor/blob/master/docs/xml-registration-reference.md)

请参阅 https://github.com/castleproject/Windsor/blob/master/docs/registering-components.md 中的拦截器和代理组件部分,了解拦截器的 xml 配置。

例如:

控制台应用程序项目(引用 aop 和业务项目)

static void Main(string[] args)
{
    var container = IocContainerFactory.GetContainer();

    ISomeBusinessService service = container.Kernel.Resolve<ISomeBusinessService>();

    Console.WriteLine(service.ReturnSomething());
    Console.ReadLine();
}

商业项目

public interface ISomeBusinessService
{
    string ReturnSomething();
}

public class SomeBusinessService : ISomeBusinessService
{
    public string ReturnSomething()
    {
        return "some business value from service";
    }
}

AOP项目(参考业务项目)

public static class IocContainerFactory
{
    public static IWindsorContainer GetContainer()
    {
        var container = new WindsorContainer();

        container.Register(Component.For<IInterceptor>().ImplementedBy<TraceLoggingInterceptor>().LifestyleTransient());
        container.Register(Component.For<ISomeBusinessService>().ImplementedBy<SomeBusinessService>().LifestyleTransient().Interceptors<TraceLoggingInterceptor>());

        return container;
    }
}

public class TraceLoggingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        Console.WriteLine("{0} - {1}", invocation.TargetType, invocation.Method);
        invocation.Proceed();
    }
}