【问题标题】:Architecting applications with Castle Windsor使用 Castle Windsor 构建应用程序
【发布时间】:2015-08-04 22:16:45
【问题描述】:

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

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

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

【问题讨论】:

  • 你可以用XML配置组件github.com/castleproject/Windsor/blob/master/docs/…,这不需要rebuild,也可以由project 2来控制aop,你可以让project 1调用project 2来注册IOC 服务,从此时起,您可以注册拦截器以充当方面并将它们应用于您希望的任何组件,项目 2 将需要引用项目 1 或包含您希望注册的接口和实现的项目。
  • @BhavO - 当你说注册拦截器作为方面后,我们可以将它们应用到任何组件(业务方法),这是否意味着我们必须编写一些 C# 代码在业务方法上应用到什么?如果我们在业务相关项目中编写任何内容,则需要重新构建。我是正确解释它还是有办法在业务项目中不写任何东西仍然实现拦截?
  • 另外,stackoverflow.com/questions/31783755/… 显示我的 xml 配置缺少某些内容,并且我无法使用 xml 配置来注册拦截器。如果你也能去那里看看就好了。
  • 您不必更改业务代码,您可以直接注册拦截器,在项目 2 中,您将引用业务项目并针对该接口注册任何自定义拦截器。您可以完全避免 xml 配置并在项目 2 中进行,您将重建项目 2 将其放入,然后重新启动应用程序。你也可以用xml注册拦截器(github.com/castleproject/Windsor/blob/master/docs/…
  • 请参阅github.com/castleproject/Windsor/blob/master/docs/… 中的拦截器和代理组件部分,了解拦截器的 xml 配置

标签: castle-windsor castle-dynamicproxy


【解决方案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 配置。

例如:

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

【讨论】:

  • 我很快在这些线上创建了两个解决方案,但没有成功。业务操作虽然在方面项目中注册了拦截,但没有被拦截。如果您可以创建一个快速的 PoC 并分享这些发现,那就太好了。我现在必须取消将此标记为答案。
  • 是使用您在aop项目中创建的容器的业务项目,并且设置拦截器是标准的,网上有很多示例这里是一个blog.andreloker.de/post/2009/02/20/…,请参阅文章末尾下载
  • 容器的创建和配置必须在aop项目中进行,业务项目必须引用aop项目来获取容器,即 IOCContainerFactory.GetContainer() ,这将是一个入口点aop 类为其创建一个容器并注册业务类和拦截器,如示例文章中所示:blog.devdave.com/2013/04/…
  • 我之前看过这些博客。这两篇文章都在一个程序集中工作。
  • 是的,为了简单起见,他们用一个项目构建了示例,但是您可以将项目的一部分吐出到一个单独的项目中,它仍然可以工作,这使您可以将它作为一个单独的程序集(dll ),并且不必修改业务 dll。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 2015-03-24
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多