Nir*_*ngh 5 c# dependency-injection castle-windsor
如何使用 Castle Windsor(使用代码)配置具有多个具体实现的接口。下面是示例代码。
public interface ICostCalculator
{
double CalculateTotal(Order order);
}
public class DefaultCostCalculator : ICostCalculator
{
public double CalculateTotal(Order order)
{
return
order.Items.Sum(x => x.Product.Rate * x.Quantity);
}
}
Run Code Online (Sandbox Code Playgroud)
该ServiceTaxCalculator实施:
public class ServiceTaxCalculator : ICostCalculator
{
private readonly ICostCalculator calculator;
private double serviveTaxRate = 10.2;
public ServiceTaxCalculator(ICostCalculator calculator)
{
this.calculator = calculator;
}
public double ServiceTaxRate
{
get { return this.serviceTaxRate; }
set { this.serviceTaxRate = value; }
}
public double CalculateTotal(Order order)
{
double innerTotal =
this.calculator.CalculateTotal(order);
innerTotal += innerTotal * servieTaxRate / 100;
return innerTotal;
}
}
Run Code Online (Sandbox Code Playgroud)
我想要一个基于服务税适用性的具体类的实例。如果适用服务税,我还需要ServiceTaxCalculator其他DefaultCostCalculator。
如何使用 Castle Windsor 配置此场景。
这是一种方法:
container.Register(Component
.For<ICostCalculator>()
.UsingFactoryMethod(k =>
isServiceTaxApplicable ?
(ICostCalculator)k.Resolve<ServiceTaxCalculator>() :
k.Resolve<DefaultCostCalculator>()));
container.Register(Component.For<DefaultCostCalculator, ICostCalculator>());
container.Register(Component.For<ServiceTaxCalculator>());
Run Code Online (Sandbox Code Playgroud)
请注意,isServiceTaxApplicable此示例中的变量是一个外部变量(未显示),但您可以轻松地将其替换为其他一些布尔检查。
还要注意 DefaultCostCalculator 将注册转发到 ICostCalculator 接口。但是,由于这不是该接口的第一次注册,因此它不是默认注册。
在工厂方法之后注册 DefaultCostCalculator 很重要,因为这会在选择 ServiceTaxCalculator 的情况下启用装饰器模式。
由于我们真的不知道您需要如何确定服务税是否适用,因此我想在马克的好答案中添加另一个解决方案。这里我使用装饰器模式:
// Decorator
public class ServiceTaxApplicableCostCalculator
: ICostCalculator
{
private readonly ICostCalculator with;
private readonly ICostCalculator without
ServiceTaxApplicableCostCalculator(
ICostCalculator with, ICostCalculator without)
{
this.with = with;
this.without = without;
}
public double CalculateTotal(Order order)
{
bool withTax = this.IsWithTax(order);
var calculator = withTax ? this.with : this.without;
return calculator.CalculateTotal(order);
}
private bool IsWithTax(Order order)
{
// determine if the order is with or without tax.
// Perhaps by using a config setting or by querying
// the database.
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以注册这个装饰器:
container.Register(Component.For<ServiceTaxCalculator>());
container.Register(
Component.For<DefaultCostCalculator, ICostCalculator>());
container.Register(Component.For<ICostCalculator>()
.UsingFactoryMethod(k =>
new ServiceTaxApplicableCostCalculator(
k.Resolve<ServiceTaxCalculator>(),
k.Resolve<DefaultCostCalculator>())
)
);
Run Code Online (Sandbox Code Playgroud)