关于c#:为什么我必须使用IoC unity

why I have to use IoC unity

本问题已经有最佳答案,请猛点这里访问。

我创建了一个应用于依赖倒置原则的类,并使用依赖注入模式,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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; }
}

因此,如果我想使用BlackAndWhitePrinter,我只需创建一个实例对象,并将其与构造一起提供给我的print类,如下所示:

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

那么,我为什么要在这里使用统一或另一个国际奥委会框架呢?我已经做了我想做的,如上所述:

1
2
3
4
var unityContainer = new UnityContainer();
unityContainer.RegisterType<ITypeOfPrinter, BlackAndWhitePrinter>();
var print = unityContainer.Resolve<Print>();
string colorfullText = print.print();


依赖注入作为一种模式有助于使应用程序代码更易于维护。DI框架(也称为IOC容器)可以帮助使组成根更易于维护。

但是,如果一个IOC容器不能帮助您的组成根更易于维护,那么不要在这种情况下使用它!但这并不意味着你不应该使用依赖注入或者其他模式和原则来帮助你的软件更易于维护。你应该不惜一切代价来降低你正在构建的软件的总体拥有成本。


正如史蒂文回答的一个附录,使用IOC框架有两个令人信服的理由,它不适用于您给出的简单示例,但可以很容易地应用于更复杂的应用程序;但我同意,如果您不觉得它带来了好处,您实际上不必使用它。

当您的类不是由您直接创建的,而是由框架创建的。

典型的例子是ASP.NETController/ApiController。您永远不会自己实例化这些,ASP.NET框架会为您这样做。在这种情况下,如果您的控制器具有依赖性,那么IOC框架允许您通过控制器上的接口轻松地声明这些依赖性,而不必担心它们是如何提供的。

这将分离类,并允许更简单的单元测试,因为您可以模拟/存根依赖关系。

当需要构造复杂的对象图时。下面是一个匿名的ISD,但不是我正在研究的项目中的真实图形:

1
2
3
4
5
6
7
8
9
10
11
 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时输入这个(更不用说尝试维护或调试它),我宁愿说

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

或者更现实地说:

1
2
3
4
5
6
7
8
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!
    }
}