ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

正确使用依赖注入吗?

2019-12-02 01:06:29  阅读:190  来源: 互联网

标签:dependency-injection c


我有一个从存储库检索DTO的服务层.根据DTO中的属性,我需要使用两种策略之一对DTO进行计算.我创建了一个工厂以返回适当的策略,并且我使用一个DI容器(Munq)实例化该对象.

public class CalculationFactory
{
    private readonly IDependencyResolver _resolver;
    public CalculationFactory(IDependencyResolver resolver)
    {
        ThrowIfNullArgument(resolver, "resolver", typeof(IDependencyResolver));
        _resolver = resolver;
    }

    public static ICalculation CreateCalculator(int serviceType)
    {
        switch (serviceType)
        {
            case 1: return _resolver.Resolve<ICalculation>("Type1");
            case 2: return _resolver.Resolve<ICalculation>("Type2");
            default: return _resolver.Resolve<ICalculation>("InvalidType");
        }
    }
}

这要求我在实例化工厂时传入依赖项解析器,以便可以使用它解析/实例化要使用的适当计算.这是正确的方法吗?如果要添加新的计算类型,则需要更新工厂的CreateCalculator方法并注册新的类型.

更新(长)
我担心的建议并不是很吸引人.我已经回到了.Net中Mark的DI的副本,尤其是关于重构的第6章.因此,我有一个MeterReadings类,我需要根据运行时值使用两种计算之一来计算费用.我在混合物中添加了一个抽象工厂,但在我的具体工厂中,我仍然需要重新进行适当的计算.我觉得我在这里遗漏了要点:

public enum ServiceType
{
    Actuals = 1, CopyBlock,
}

public interface IChargeCalculator
{
    decimal CalculateCharge();
}

public interface IChargeCalculatorFactory
{
    IChargeCalculator CreateChargeCalculator(ServiceType serviceType);
}

public class MeterReading
{
    private readonly IChargeCalculatorFactory chargeCalculatorFactory;
    public MeterReading(IChargeCalculatorFactory chargeCalculatorFactory)
    {
        if (chargeCalculatorFactory == null)
            throw new ArgumentNullException("chargeCalculatorFactory");
        this.chargeCalculatorFactory = chargeCalculatorFactory;    
    }
}

public class ConcreteChargeCalculatorFactory : IChargeCalculatorFactory
{
    public IChargeCalculator CreateChargeCalculator(ServiceType serviceType)
    {
        switch (serviceType)
        {
            case ServiceType.Actuals : return new ActualsChargeCalculator();
            default: return new CopyBlockChargeCalculator();
        }
    }
}

但是在我的容器中,我可以注册不同的计算器,如果我通过容器作为具体工厂,则会得到类似以下内容(未经测试),坦率地说,这对我来说相当合理.任何反馈/澄清都将受到欢迎.

Container.Register<IChargeCalculator>("Actuals",
                                      c => new ActualsChargeCalculator());
Container.Register<IChargeCalculator>("CopyBlock",
                                      c => new CopyBlockChargeCalculator());
...
public enum ServiceType
{
    Actuals = 1, CopyBlock,
}

public interface IChargeCalculator
{
    decimal CalculateCharge();
}

public class MeterReading
{
    private readonly IDependencyResolver chargeCalculatorFactory;
    private ServiceType serviceType;
    public MeterReading(IDependencyResolver chargeCalculatorFactory)
    {
        if (chargeCalculatorFactory == null)
            throw new ArgumentNullException("chargeCalculatorFactory");
        this.chargeCalculatorFactory = chargeCalculatorFactory;    
    }

    public decimal Charge
    {
        get
        {
            return chargeCalculatorFactory.Resolve<IChargeCalculator>(serviceType.ToString());
        }
    }
}

解决方法:

是的,我会说您正在以正确的方式进行操作.

尽管您写道您需要“传递依赖项解析器”,但是有没有理由不能将工厂类注入需要的类中呢?然后,工厂对依赖项解析器的依赖项应由依赖项解析器本身(针对自身)进行解析.

我希望这句话有意义.

我试图提出一个“更清洁”的解决方案,但还没有找到.当然可以使用与问题(并不完全相同)中提出的问题类似的解决方案,但我确实看到,只是将相同的代码移到另一个地方.雷莫还写道,它可以在工厂类而不是工厂方法中完成.

这有点像决定编写Lampda还是辅助类.它主要归结为可读性,对我来说,工厂方法就很大,将其放在模块初始化程序或引导程序接缝中会杂乱无章.

顺便说一句,我可以推荐Ninject,这是一个非常好的清洁DI.另外,它的文档使用忍者示例;)

标签:dependency-injection,c
来源: https://codeday.me/bug/20191202/2084665.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有