Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dependency injection 基于条件的容器解析_Dependency Injection_Inversion Of Control_Castle Windsor - Fatal编程技术网

Dependency injection 基于条件的容器解析

Dependency injection 基于条件的容器解析,dependency-injection,inversion-of-control,castle-windsor,Dependency Injection,Inversion Of Control,Castle Windsor,我试图在使用Windsor容器时实现策略模式。以下是我所拥有的: public class OrderProcessor { ... public OrderProcessor(ITaxStrategy strategy) {} public void Process(Order order) { order.Tax = strategy.CalcTax(order); } } 问题是,我如何配置我的容器(欢迎使用其他容器示例),使其基本上具有选

我试图在使用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(地址)作为注入依赖项的标准?

这里有一些选项,请选择您最喜欢的选项。我通常用第一个,它是最简单的

[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; }
    }
}
[TestFixture]
公共类税收策略测试{
[测试]
工厂()的公共空间{
var container=新的WindsorContainer();
container.AddComponent();
container.AddComponent();
container.AddComponent();
container.AddComponent();
var order=新订单{Country=“US”};
container.Resolve().Process(订单);
主张平等(10,订单税);
}
[测试]
public void InjectWithFactoryFromDictionary(){
var container=新的WindsorContainer();
container.AddFacility();
container.AddComponent();
container.AddComponent();
container.AddComponent();
container.Register(Component.For())
.UsingFactoryMethod(内核=>new TaxStrategyFactory2(新字典{
{“US”,kernel.Resolve()},
{“CA”,kernel.Resolve()},
})));
var order=新订单{Country=“US”};
container.Resolve().Process(订单);
主张平等(10,订单税);
}
[测试]
public void InjectWithProxy(){
var container=新的WindsorContainer();
container.AddComponent();
container.AddComponent();
container.AddComponent();
container.AddComponent();
container.Register(Component.For())
.短暂的
.Interceptors(InterceptorReference.ForType()).First);
var order=新订单{Country=“CA”};
container.Resolve().Process(订单);
主张平等(5,订单税);
}
公共类OrderProcessorInterceptor:IIInterceptor{
私有只读ITaxStrategyFactory strategyFactory;
公共订单处理程序接口(ITaxStrategyFactory strategyFactory){
this.strategyFactory=strategyFactory;
}
公共无效拦截(IInvocation调用){
if(invocation.MethodInvocationTarget.Name==“进程”){
var processor=(OrderProcessor2)invocation.InvocationTarget;
var order=(order)invocation.Arguments[0];
processor.Strategy=strategyFactory.Create(订单);
}
invocation.procedure();
}
}
公共接口处理器{
作废流程(订单);
}
公共类OrderProcessor2:IOrderProcessor{
公共ITaxStrategy策略{get;set;}
公共虚拟作废流程(订单){
order.Tax=Strategy.CalcTax(order);
}
}
公共类OrderProcessor:IOrderProcessor{
私有只读ITaxStrategyFactory strategyFactory;
公共订单处理器(ITaxStrategyFactory strategyFactory){
this.strategyFactory=strategyFactory;
}
公共作废流程(订单){
var strategy=strategyFactory.Create(订单);
order.Tax=strategy.CalcTax(order);
}
}
公共接口ITaxStrategyFactory{
ITaxStrategy创建(订单o);
}
公共类税收战略工厂:ITaxStrategyFactory{
私有只读IKernel内核;
公共税收战略工厂(IKernel内核){
this.kernel=内核;
}
公共ITaxStrategy创建(订单o){
如果(海外国家=“美国”)
返回kernel.Resolve();
返回kernel.Resolve();
}
}
公共类税收战略工厂2:ITaxStrategyFactory{
私有只读词典策略;
公共税收策略工厂2(词典策略){
这就是战略=战略;
}
公共ITaxStrategy创建(订单o){
返回策略[o.Country];
}
}
公共接口ITAX策略{
十进制CalcTax(订单);
}
公共类USTaxStrategy:ITaxStrategy{
公共十进制计算器(订单){
返回10;
}
}
公共类CanadatXstrategy:ITaxStrategy{
公共十进制计算器(订单){
返回5;
}
}
公共阶级秩序{
公共字符串国家{get;set;}
公共十进制税{get;set;}
}
}

简短回答:编写一个TaxStrategyFactoryHmm-在构建过程中,您将如何向工厂提供参数?非常简单,谢谢Mauricio。我希望温莎有某种标准设施可以(呃)促进选择,并且我可以在没有工厂中间商的情况下依赖ITaxStrategy。这是不可能的,因为容器必须知道特定的订单实例,因此需要代理解决方案。另一种选择是将订单转移到某种上下文中,但这会使事情变得更加复杂。对于那些未来关注的人,我将发布一篇文章并提供一个VS 2K8解决方案示例。