使用Castle Windsor构建应用程序

时间:2015-08-04 07:01:43

标签: castle-windsor castle-dynamicproxy

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

1)是否可以在Project 1中使用xml配置文件来配置在运行时应用哪些方面? (我对这种可能性有一个很好的想法,但如果不然,请告诉我)

2)是否有可能不接触项目1(代码更改/重建)以添加新方面/删除旧方面并通过项目2管理所有这些?换句话说,由于未来添加或删除方面,我不想更改/构建我的业务解决方案。

1 个答案:

答案 0 :(得分:1)

您可以使用XML(https://github.com/castleproject/Windsor/blob/master/docs/registering-components.md)配置组件,这不需要重建,项目2也可以配置AOP,您可以让项目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 configuratino。

所以例如:

控制台应用项目(参考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();
    }
}