基于标准的容器解析

发布于 2024-08-09 05:41:27 字数 485 浏览 6 评论 0原文

我试图在使用 Windsor 容器时实现策略模式。这就是我所遇到的:

public class OrderProcessor {
...
    public OrderProcessor(ITaxStrategy strategy) {}

    public void Process(Order order)
    { 
      order.Tax = strategy.CalcTax(order);
    }
}

问题是,如何配置我的容器(欢迎其他容器示例)以基本上具有选择适当依赖项的标准。因此,如果我注册以下内容,

public class USTaxStrategy : ITaxStrategy { ... }
public class CanadaTaxStrateg : ITaxStrategy { ... }

如何使用 Order.Destination(地址)作为注入依赖项的标准?

I'm trying to implement the Strategy pattern while using Windsor container. Here is what I have:

public class OrderProcessor {
...
    public OrderProcessor(ITaxStrategy strategy) {}

    public void Process(Order order)
    { 
      order.Tax = strategy.CalcTax(order);
    }
}

The problem is, how do I configure my container (other container examples welcome) to have, essentially, criteria for choosing the appropriate dependency. So if I register the following

public class USTaxStrategy : ITaxStrategy { ... }
public class CanadaTaxStrateg : ITaxStrategy { ... }

how do I use the Order.Destination (address) as the criteria for the injected dependency?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不打扰别人 2024-08-16 05:41:27

这里有几个选项,选择您最喜欢的一个。我一般用第一个,最简单。

[TestFixture]
public class TaxStrategyTests {
    [Test]
    public void InjectWithFactory() {
        var container = new WindsorContainer();
        container.AddComponent<USTaxStrategy>();
        container.AddComponent<CanadaTaxStrategy>();
        container.AddComponent<OrderProcessor>();
        container.AddComponent<ITaxStrategyFactory, TaxStrategyFactory>();
        var order = new Order {Country = "US"};
        container.Resolve<OrderProcessor>().Process(order);
        Assert.AreEqual(10, order.Tax);
    }

    [Test]
    public void InjectWithFactoryFromDictionary() {
        var container = new WindsorContainer();
        container.AddFacility<FactorySupportFacility>();
        container.AddComponent<USTaxStrategy>();
        container.AddComponent<CanadaTaxStrategy>();
        container.AddComponent<OrderProcessor>();
        container.Register(Component.For<ITaxStrategyFactory>()
                               .UsingFactoryMethod(kernel => new TaxStrategyFactory2(new Dictionary<string, ITaxStrategy> {
                                   {"US", kernel.Resolve<USTaxStrategy>()},
                                   {"CA", kernel.Resolve<CanadaTaxStrategy>()},
                               })));
        var order = new Order { Country = "US" };
        container.Resolve<OrderProcessor>().Process(order);
        Assert.AreEqual(10, order.Tax);
    }

    [Test]
    public void InjectWithProxy() {
        var container = new WindsorContainer();
        container.AddComponent<USTaxStrategy>();
        container.AddComponent<CanadaTaxStrategy>();
        container.AddComponent<OrderProcessorInterceptor>();
        container.AddComponent<ITaxStrategyFactory, TaxStrategyFactory>();
        container.Register(Component.For<OrderProcessor2>()
                               .LifeStyle.Transient
                               .Interceptors(InterceptorReference.ForType<OrderProcessorInterceptor>()).First);
        var order = new Order {Country = "CA"};
        container.Resolve<OrderProcessor2>().Process(order);
        Assert.AreEqual(5, order.Tax);
    }

    public class OrderProcessorInterceptor : IInterceptor {
        private readonly ITaxStrategyFactory strategyFactory;

        public OrderProcessorInterceptor(ITaxStrategyFactory strategyFactory) {
            this.strategyFactory = strategyFactory;
        }

        public void Intercept(IInvocation invocation) {
            if (invocation.MethodInvocationTarget.Name == "Process") {
                var processor = (OrderProcessor2) invocation.InvocationTarget;
                var order = (Order) invocation.Arguments[0];
                processor.Strategy = strategyFactory.Create(order);
            }
            invocation.Proceed();
        }
    }

    public interface IOrderProcessor {
        void Process(Order order);
    }

    public class OrderProcessor2 : IOrderProcessor {
        public ITaxStrategy Strategy { get; set; }

        public virtual void Process(Order order) {
            order.Tax = Strategy.CalcTax(order);
        }
    }

    public class OrderProcessor : IOrderProcessor {
        private readonly ITaxStrategyFactory strategyFactory;

        public OrderProcessor(ITaxStrategyFactory strategyFactory) {
            this.strategyFactory = strategyFactory;
        }

        public void Process(Order order) {
            var strategy = strategyFactory.Create(order);
            order.Tax = strategy.CalcTax(order);
        }
    }

    public interface ITaxStrategyFactory {
        ITaxStrategy Create(Order o);
    }

    public class TaxStrategyFactory : ITaxStrategyFactory {
        private readonly IKernel kernel;

        public TaxStrategyFactory(IKernel kernel) {
            this.kernel = kernel;
        }

        public ITaxStrategy Create(Order o) {
            if (o.Country == "US")
                return kernel.Resolve<USTaxStrategy>();
            return kernel.Resolve<CanadaTaxStrategy>();
        }
    }

    public class TaxStrategyFactory2: ITaxStrategyFactory {
        private readonly IDictionary<string, ITaxStrategy> strategies;

        public TaxStrategyFactory2(IDictionary<string, ITaxStrategy> strategies) {
            this.strategies = strategies;
        }

        public ITaxStrategy Create(Order o) {
            return strategies[o.Country];
        }
    }

    public interface ITaxStrategy {
        decimal CalcTax(Order order);
    }

    public class USTaxStrategy : ITaxStrategy {
        public decimal CalcTax(Order order) {
            return 10;
        }
    }

    public class CanadaTaxStrategy : ITaxStrategy {
        public decimal CalcTax(Order order) {
            return 5;
        }
    }

    public class Order {
        public string Country { get; set; }
        public decimal Tax { get; set; }
    }
}

Here are a few options, pick the one you like best. I usually use the first one, it's the simplest.

[TestFixture]
public class TaxStrategyTests {
    [Test]
    public void InjectWithFactory() {
        var container = new WindsorContainer();
        container.AddComponent<USTaxStrategy>();
        container.AddComponent<CanadaTaxStrategy>();
        container.AddComponent<OrderProcessor>();
        container.AddComponent<ITaxStrategyFactory, TaxStrategyFactory>();
        var order = new Order {Country = "US"};
        container.Resolve<OrderProcessor>().Process(order);
        Assert.AreEqual(10, order.Tax);
    }

    [Test]
    public void InjectWithFactoryFromDictionary() {
        var container = new WindsorContainer();
        container.AddFacility<FactorySupportFacility>();
        container.AddComponent<USTaxStrategy>();
        container.AddComponent<CanadaTaxStrategy>();
        container.AddComponent<OrderProcessor>();
        container.Register(Component.For<ITaxStrategyFactory>()
                               .UsingFactoryMethod(kernel => new TaxStrategyFactory2(new Dictionary<string, ITaxStrategy> {
                                   {"US", kernel.Resolve<USTaxStrategy>()},
                                   {"CA", kernel.Resolve<CanadaTaxStrategy>()},
                               })));
        var order = new Order { Country = "US" };
        container.Resolve<OrderProcessor>().Process(order);
        Assert.AreEqual(10, order.Tax);
    }

    [Test]
    public void InjectWithProxy() {
        var container = new WindsorContainer();
        container.AddComponent<USTaxStrategy>();
        container.AddComponent<CanadaTaxStrategy>();
        container.AddComponent<OrderProcessorInterceptor>();
        container.AddComponent<ITaxStrategyFactory, TaxStrategyFactory>();
        container.Register(Component.For<OrderProcessor2>()
                               .LifeStyle.Transient
                               .Interceptors(InterceptorReference.ForType<OrderProcessorInterceptor>()).First);
        var order = new Order {Country = "CA"};
        container.Resolve<OrderProcessor2>().Process(order);
        Assert.AreEqual(5, order.Tax);
    }

    public class OrderProcessorInterceptor : IInterceptor {
        private readonly ITaxStrategyFactory strategyFactory;

        public OrderProcessorInterceptor(ITaxStrategyFactory strategyFactory) {
            this.strategyFactory = strategyFactory;
        }

        public void Intercept(IInvocation invocation) {
            if (invocation.MethodInvocationTarget.Name == "Process") {
                var processor = (OrderProcessor2) invocation.InvocationTarget;
                var order = (Order) invocation.Arguments[0];
                processor.Strategy = strategyFactory.Create(order);
            }
            invocation.Proceed();
        }
    }

    public interface IOrderProcessor {
        void Process(Order order);
    }

    public class OrderProcessor2 : IOrderProcessor {
        public ITaxStrategy Strategy { get; set; }

        public virtual void Process(Order order) {
            order.Tax = Strategy.CalcTax(order);
        }
    }

    public class OrderProcessor : IOrderProcessor {
        private readonly ITaxStrategyFactory strategyFactory;

        public OrderProcessor(ITaxStrategyFactory strategyFactory) {
            this.strategyFactory = strategyFactory;
        }

        public void Process(Order order) {
            var strategy = strategyFactory.Create(order);
            order.Tax = strategy.CalcTax(order);
        }
    }

    public interface ITaxStrategyFactory {
        ITaxStrategy Create(Order o);
    }

    public class TaxStrategyFactory : ITaxStrategyFactory {
        private readonly IKernel kernel;

        public TaxStrategyFactory(IKernel kernel) {
            this.kernel = kernel;
        }

        public ITaxStrategy Create(Order o) {
            if (o.Country == "US")
                return kernel.Resolve<USTaxStrategy>();
            return kernel.Resolve<CanadaTaxStrategy>();
        }
    }

    public class TaxStrategyFactory2: ITaxStrategyFactory {
        private readonly IDictionary<string, ITaxStrategy> strategies;

        public TaxStrategyFactory2(IDictionary<string, ITaxStrategy> strategies) {
            this.strategies = strategies;
        }

        public ITaxStrategy Create(Order o) {
            return strategies[o.Country];
        }
    }

    public interface ITaxStrategy {
        decimal CalcTax(Order order);
    }

    public class USTaxStrategy : ITaxStrategy {
        public decimal CalcTax(Order order) {
            return 10;
        }
    }

    public class CanadaTaxStrategy : ITaxStrategy {
        public decimal CalcTax(Order order) {
            return 5;
        }
    }

    public class Order {
        public string Country { get; set; }
        public decimal Tax { get; set; }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文