通过依赖注入理解IoC的问题

时间:2012-09-18 13:40:02

标签: c# interface dependency-injection inversion-of-control

我正试着绕过IoC w。依赖注入和我关注了Joel Abrahamsson撰写的这篇博文:http://joelabrahamsson.com/entry/inversion-of-control-introduction-with-examples-in-dotnet

我已经设置了这样的项目:

  • 模型
  • 接口
  • 控制器
  • DAL

我的课程如下:

汽车

public class Car
{
    public int Id { get; set; }
    public string Brand { get; set; }
    public string Year { get; set; }
}

CarController

public class CarController
 {
     private readonly ICar _carInterface;

     public CarController(ICar car)
     {
         _carInterface = car;
     }

     public void SaveCar(Car car)
     {
          _carInterface.SaveCar(car);
     }
}

ICar界面

public interface ICar
{
    void SaveCar(Car car);
}

DbCar

public class DbCar: ICar
{
    public void SaveCar(Car car)
    {
        throw new NotImplementedException();
    }
}

现在,在用户界面上,我不知道如何处理这个问题;-)我可以肯定地制作出我需要的Car对象,但是当新建一个CarController时,它(当然)期望一个我不能给它的ICar界面。

我有一种感觉,我在阅读Joels(伟大)文章的过程中误解了一些东西:-)而且我希望也许有人能够揭示我错过/误解的内容。

非常感谢任何帮助/提示!

提前多多感谢。

一切顺利,

2 个答案:

答案 0 :(得分:2)

看起来ICar不是汽车的接口。相反,它是用于保存汽车的存储库的接口。因此它应该被称为ICarRepository(或可能是IGarage。)

你说:

  

但是当新推出CarController时,它(当然)需要一个ICar   接口,我不能给它。

为什么不呢?您有一个实现DbCar。为什么你不能给它一个呢?

您在评论中询问了这个表达式:

new CarController(new DbCar())

具体而言,通过编写该行代码,您已将控制器绑定到汽车存储库的特定实现。

这是真的,但仅限于那种情况。在单元测试的其他地方你可以写:

new CarController(new FakeCarRepository())

CarController类是一个独立的模块,它的构造函数参数列表清楚地依赖于其他东西。

IoC或“依赖注入”框架是提供构造CarController等类的标准方法的库,因此它所需的参数将在配置文件中指定。但对于一个简单的应用程序来说,这可能有点过头了。

答案 1 :(得分:0)

要正确执行依赖注入和控制反转,您应该遵循基于接口的开发(SOLID原则中的“I”)。下面是我如何组织你的类和接口,以便能够最大程度地解决这个问题。

ICar界面

public interface ICar
{
    int Id { get; set; }
    string Brand { get; set; }
    string Year { get; set; }
}

<强>汽车

public class Car : ICar
{
    public int Id { get; set; }
    public string Brand { get; set; }
    public string Year { get; set; }
}

ICarRepository界面

public interface ICarRepository
{
    void SaveCar(ICar car);
}

<强> CarRepository

public class CarRepository : ICarRepository
{
    public void SaveCar(ICar car)
    {
        throw new NotImplementedException();
    }
}

ICarController界面

public interface ICarController
{
     void SaveCar(ICar car);
}

<强> CarController

public class CarController : ICarController
{
     private readonly ICarRepository _carRepository;

     public CarController(ICarRepository carRepository)
     {
         _carRepository = carRepository;
     }

     public void SaveCar(ICar car)
     {
          _carRepository.SaveCar(car);
     }
}

然后你可以:

ICarRepository carRepository = new CarRepository();
ICarController carController = new CarController(carRepository);
ICar carOne = new Car { Id = 1, Brand = "Ford", Year = "2010" };
ICar carTwo = new Car { Id = 2, Brand = "Dodge", Year = "1999" };

carController.SaveCar(carOne);
carController.SaveCar(carTwo);