tuc*_*caz 5 c# dependency-injection ninject inversion-of-control
我在排序管理类中自动解析和手动依赖的方法时遇到了一些麻烦.
假设我有两个课程来计算价格:一个计算我将收取多少运费,另一个计算我将为整个订单收取多少费用.第二个使用第一个,以便将运费与整个订单价格相加.
这两个类都依赖于第三类,我将其称为ExchangeRate,它给出了我应该用于计算价格的汇率.
到目前为止,我们有这种依赖链:
OrderCalculator - > ShippingCalculator - > ExchangeRate
我正在使用Ninject来解决这些依赖关系,这一直在使用.现在我要求ExchangeRate类返回的速率将根据将在构造函数中提供的参数而变化(因为对象不能在没有这个的情况下工作,因此要使依赖项显式放置在构造函数上)来自用户输入.因此,我无法再自动解析我的依赖项.
每当我想要OrderCalculator或依赖于ExchangeRate的任何其他类时,我都不能要求Ninject容器解析它,因为我需要在构造函数中提供参数.
在这种情况下你有什么建议?
谢谢!
编辑:我们添加一些代码
这个对象链由WCF服务使用,我使用Ninject作为DI容器.
public class OrderCalculator : IOrderCalculator
{
private IExchangeRate _exchangeRate;
public OrderCalculator(IExchangeRate exchangeRate)
{
_exchangeRate = exchangeRate;
}
public decimal CalculateOrderTotal(Order newOrder)
{
var total = 0m;
foreach(var item in newOrder.Items)
{
total += item.Price * _exchangeRate.GetRate();
}
return total;
}
}
public class ExchangeRate : IExchangeRate
{
private RunTimeClass _runtimeValue;
public ExchangeRate(RunTimeClass runtimeValue)
{
_runtimeValue = runtimeValue;
}
public decimal GetRate()
{
//returns the rate according to _runtimeValue
if(_runtimeValue == 1)
return 15.3m;
else if(_runtimeValue == 2)
return 9.9m
else
return 30m;
}
}
//WCF Service
public decimal GetTotalForOrder(Order newOrder, RunTimeClass runtimeValue)
{
//I would like to pass the runtimeValue when resolving the IOrderCalculator depedency using a dictionary or something
//Something like this ObjectFactory.Resolve(runtimeValue);
IOrderCalculator calculator = ObjectFactory.Resolve();
return calculator.CalculateOrderTotal(newOrder);
}
与往常一样,当您对运行时值具有部分依赖性时,解决方案是抽象工厂.
这样的事情应该有效:
public interface IExchangeRateFactory
{
ExchangeRate GetExchangeRate(object runTimeValue);
}
Run Code Online (Sandbox Code Playgroud)
现在将IExchangeRateFactory注入到使用者而不是ExchangeRate中,并使用GetExchangeRate方法将运行时值转换为ExchangeRate实例.
显然,您还需要提供IExchangeRateFactory的实现并配置NInject以将接口映射到您的实现.
我最终做了一些完全不同的事情。
在调用 ObjectFactory 为我解决依赖关系之前,我使用 runTimeValue 创建 IExchangeRate 的一个新实例,并告诉 IoC/DI 容器使用它而不是创建一个新实例。这样,整个对象链都被保留,并且不需要工厂。
//WCF Service
public decimal GetTotalForOrder(Order newOrder, RunTimeClass runtimeValue)
{
IExchangeRate ex = new ExchangeRate(runtimeValue);
IOrderCalculator calculator = ObjectFactory.With<IExchangeRate>(ex).GetInstance();
return calculator.CalculateOrderTotal(newOrder);
}
Run Code Online (Sandbox Code Playgroud)
但由于 Ninject 没有办法做到这一点(只能重新绑定,这不是我想要的),我将容器更改为 StructureMap。
感谢大家的帮助!真的很感激!
| 归档时间: |
|
| 查看次数: |
1019 次 |
| 最近记录: |