c# - 解决自动和手动依赖关系

标签 c# dependency-injection inversion-of-control ninject

我在寻找一种方法来管理我的类中的自动解决和手动依赖项时遇到了一些麻烦。

假设我有两个类来计算价格:一个计算我将收取多少运费,另一个计算我将对整个订单收取多少。第二个使用第一个,以便将运费与整个订单价格相加。

这两个类都依赖于第三个类,我称之为 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);    
}

最佳答案

与往常一样,当您对运行时值有部分依赖时,the solution is an Abstract Factory .

像这样的东西应该可以工作:

public interface IExchangeRateFactory
{
    ExchangeRate GetExchangeRate(object runTimeValue);
}

现在将 IExchangeRateFactory 而不是 ExchangeRate 注入(inject)到您的消费者中,并使用 GetExchangeRate 方法将运行时值转换为 ExchangeRate 实例。

显然,您还需要提供 IExchangeRateFactory 的实现并配置 NInject 以将接口(interface)映射到您的实现。

关于c# - 解决自动和手动依赖关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3335735/

相关文章:

c# - 作为装饰者登录 vs. 依赖注入(inject)——如果我需要在类里面登录怎么办?

c# - Autofac 使用 InjectProperties 自动注入(inject)依赖项或使用 Resolve<> 手动解析

symfony - 使配置节点在 Symfony 2 配置中同时支持字符串和数组?

inversion-of-control - 使用 Spring.Net 属性注入(inject)数组

c# - 为什么我必须在 ASP.NET MVC 中进行 "wire up"依赖注入(inject)?

c# - HttpClient HttpRequestException

c# - 哈希集内存开销

c# - C#-随机数生成器错误

c# - 验证 Ajax 加载的表单 - 返回验证摘要

c# - Autofac - 在解析时在 .OnActivated 方法中传递一个值