为什么我必须使用IoC Unity

4
我创建了一个符合依赖反转原则的类,并使用了依赖注入模式,代码如下:

public interface ITypeOfPrinter
{
    string Printing();
}

public class Print
{  
    private readonly ITypeOfPrinter _typeOfPrinter;

    public Print(ITypeOfPrinter typeOfPrinter)
    {
        _typeOfPrinter = typeOfPrinter;
    }

    public string print()
    {
        return _typeOfPrinter.Printing();
    }
}

public class BlackAndWhitePrinter : ITypeOfPrinter
{
    public string Printing()
    {
        NumberOfPrints++;
        return string.Format("it is Black and white printing {0}", NumberOfPrints);
    }

    public int NumberOfPrints { get; set; }

}
public class ColorfullPrinter : ITypeOfPrinter
{
    public string Printing()
    {
        NumberOfPrints++;
        return string.Format("it is colorfull printing {0}", NumberOfPrints);
    }
    public int NumberOfPrints { get; set; }
}

如果我想要使用黑白打印机,我只需要创建一个实例对象并将其作为构造函数的参数传递给我的打印类,具体如下:

ITypeOfPrinter typeofprinter = new BlackAndWhitePrinter();
Print hp = new Print(typeofprinter);
hp.print();

那么为什么我要在这里使用Unity或其他IoC框架?我已经按照上述完成了我想要的内容。
var unityContainer = new UnityContainer();
unityContainer.RegisterType<ITypeOfPrinter, BlackAndWhitePrinter>();
var print = unityContainer.Resolve<Print>();
string colorfullText = print.print();

4
符合依赖倒置原则并不一定需要使用控制反转容器。请参阅http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/。 - Preston Guillot
2个回答

7

依赖注入被视为一种模式,可以帮助使您的应用程序代码更易于维护。DI框架(也称为IoC容器)可以帮助使组合根更易于维护。

但是,如果IoC容器不能帮助使您的组合根更易于维护,请不要在该场景中使用它!这并不意味着您不应该使用依赖注入或其他有助于使软件更易于维护的模式和原则。您应该尽力降低正在构建的软件的总拥有成本


6
作为对Steven回答的补充,使用IOC框架有一些令人信服的理由,这些理由在你提供的简单示例中并不适用,但很容易适用于更复杂的应用程序;但我同意,如果您认为它没有带来好处,那么您实际上不必使用它。
当您的类不是直接由您创建,而是由框架创建时。
这种情况的典型例子是ASP.NET Controller / ApiController。您从未自己实例化这些内容,而是由ASP.NET框架为您完成。在这种情况下,如果您的控制器具有依赖关系,则IOC框架允许您轻松地通过接口在控制器上声明这些依赖关系,而不必担心如何提供它们。
这将解耦您的类,并允许更轻松的单元测试,因为您可以模拟/存根依赖项。
当您有复杂的对象图需要构建时。以下是我正在处理的项目中的匿名但真实的图形:
 new DeathStar(new NotAMoon(),
               new PlanetExploder(),
                new ExhaustPort(new CriticalVulnerabilityIgnorer()),
                new StormTrooperGenerator(new DodgyBlasterGenerator(),
                    new HeadDoorBumper(new Ouch()),
                    new ShieldGenerator(new FurryCreatureVulnerability)),
                    new DramaticDuel(new Saber()), new DeadJedi()),
                new DroidFactory(),
                new TrashCompactor(new Monster()),
                new Emperor(new Vader())
            );

不知道你怎么看,但如果我需要一颗新的IDeathStar,我肯定不想要打这么长的代码(更别提维护和调试了),我宁愿这样说:

var moon= IOCFrameworkOfChoice.Resolve<IDeathStar>();

更加现实的情况是:
public class MyController: Controller
{
    public MyController(IDeathStar star)
    {
        //at runtime, at this point I have an armed and fully operational IDeathStar
        //without having to worry about where it came from!
    }
}

2
+1 for new HeadDoorBumper(new Ouch()) :-) (笑) - Maarten
1
我喜欢CriticalVulnerabilityIgnorer()。 - bryanbcook
2
如果他们进行了单元测试就好了... - Stephen Byrne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接