asp.net mvc 5 - 在类的每个方法中创建相同类的实例

时间:2017-02-07 20:50:04

标签: c# asp.net-mvc instance repository-pattern

我有一个问题。

我刚刚在一家拥有一名“高级开发人员”的新公司开始工作。

在课堂上他正在这样做(例子):

class CarController{


public Cars GetCars(){

    **Connection connect = new Connection(); // Create DB connection**

    //and here some fetching of the data and returning it with a HTTP Response
}



public Cars GetCar(int id){

    **Connection connect = new Connection(); // Create DB connection**

    //and here some fetching the car with id, returning it with a HTTP Response
}

//and this pattern continues here...

}

我无法想象这是一个很好的做法,在每个方法中继续创建一个类的相同实例来调用数据库? 内存在各处创建实例是不是也不好?

在我看来,我们可以使用存储库模式,只允许访问实现接口的类的数据库类。 现在我们将Database类暴露给控制器,代码紧密耦合!

他说他无法理解存储库的概念,这就是为什么在这种情况下应该使用接口。

你如何说服一位大四学生重构代码,并向他证明他的编码没有良好的结构?

我如何以其他方式解释上述代码中的缺点?

3 个答案:

答案 0 :(得分:3)

  

我无法想象,在每个方法中创建相同的类实例来调用数据库是一个好习惯吗?内存在各处创建实例是不是也不好?

在这种情况下,它实际上是 IS 的最佳做法。 .NET池数据库连接,因此创建它们通常不是一个昂贵的过程。但是,重用连接可能会导致问题。

但是,您应该在完成连接后立即处理连接。一个方便的方法是使用using语句:

using(Connection connect = new Connection()) // Create DB connection
{
       //and here some fetching of the data and returning it with a HTTP Response
}  // the connection is closed and disposed of here.
  

在我看来,我们可以使用存储库模式,只允许访问实现接口的类的数据库类。现在我们将Database类暴露给控制器,代码紧密耦合!

当然,这可能是一种改进,但它与你的第一个问题正交。存储库应在需要时创建连接,并在完成后处理它。

  

你如何说服一位大四学生重构代码,并向他证明他的编码没有良好的结构?

如果你刚刚开始,如果你接近这种方式,你可能无法做到。请记住,大多数人(不论经验)都不喜欢别人批评他们的工作。相反,提供替代解决方案,并提供一些原因,说明为什么它是改进而非当前设计。一种务实的方法是提供一种情况,其中现有的模式会导致问题(单元测试是最明显的),并说明为什么不同的设计可以解决这个问题。

答案 1 :(得分:1)

直接实例化对象并不总是坏的

在不使用IoC容器的情况下创建对象实例并不总是坏事(想象一下,如果我们每次想要创建string时都使用Container.Resolve!)如果依赖项不是volatile dependency那么它可能不是DI的好选择。

不,它不贵

反复创建和处理数据库连接并不昂贵(它们是从池中分配并保持打开状态),实际上被视为best practice

注入数据库连接?

在数据库连接的情况下,必须严格处理该连接并在快速时间范围内进行处理,因此有一个参数可以不注入它。您当然不希望调用者(或组合根)实例化连接,然后要求连接的使用者处理它;这违反了两个共同原则:

  1. 创建实例的范围也应该销毁它
  2. 注入的实例应该比使用注入的实例的对象具有更长的生命周期
  3. 注入工厂?

    也许您可以注入数据库连接工厂,但这有点问题,因为IDBConnection不包含SqlConnection中找到的所有成员。因此,如果你想在这里使用DI,你需要提供一个具体的实例(顺便说一下,这是密封的,所以没有垫片),或者你需要从你的实现中剥离所有SQL专用的功能。 SqlCommand也是如此 - IDBCommand只有一小部分属性,而且根本没有异步方法。

    你会得到什么?

    它会让你松耦合吗?并不是的。你有一种假松散耦合,但数据访问类和SQL服务器数据库之间存在隐式逻辑耦合(例如,它们有一个共同的模式)。这不像你可以用OracleClient替换你的SqlClient并期望它能够工作。多年来我见过很多人尝试过它;如果你还在尝试,你还没有流行起来。它不起作用。功能丰富的数据库客户端将在数据库平台上具有一些硬依赖性。

    单元测试会更容易吗?不确定。正如我上面提到的,你不能真正编写填充程序或存根,因为SqlConnection,SqlCommand,SqlParameter等都是密封的,并且都具有接口中找不到的具体方法。无论如何,你仍然会被嘲笑而不是顽固。

    长期计划是什么?

    也许计划是在将来某个时候用EF替换所有那些低级SQL的东西。如果是这样的话,那么在此时将DI改装到DAL将是浪费时间,因为它最终都会被扔掉。

    我的结论

    这是一个判断电话。你的同事有权成功。我会专注于其他更明显,更低级的重构结果。

答案 2 :(得分:-2)

向他解释" SOLID"设计原则。举例并解释接口和设计模式的使用。可能应该有点亮!

问他如何用他的代码完成单元测试!