作者:ChinaSpecial | 来源:互联网 | 2022-12-10 12:28
我是C#的新手,我已经了解了构造函数,而且我了解到我们使用它们的原因是我们可以在构造时分配任何我们想要的东西,但是我很难理解的是,我有一个IRepository学生,例如:
public interface IStudentRepository
{
object getAll();
}
我在StudentRepository中实现了它:
public class StudentRepository:IStudentRepository
{
public testDBEntities DB = new testDBEntities();
public object getAll()
{
var reslt = (from s in DB.Students
select new StudentViewModel
{
Name = s.Name,
Id=s.Id
});
return reslt;
}
}
在我的homeController中,我可以执行以下操作:
IStudentRepository _repository=new StudentRepository();
public JsonResult Index()
{
var m= _repository.getAll();
return Json(m,JsonRequestBehavior.AllowGet);
}
为什么我应该有一个构造函数呢?
IStudentRepository _repository=new StudentRepository();
public HomeController(StudentRepository _repository)
{
this._repository = _repository;
}
public JsonResult Index()
{
var m= _repository.getAll();
return Json(m,JsonRequestBehavior.AllowGet);
}
抱歉,如果我的问题很简单,但是我找不到正确的答案,请先感谢
1> Martin Verja..:
单一责任原则
第一个优点是您HomeController
不必担心创建StudentRepository
对象。其他人已经实例化它,它是从数据库,文件或用户输入等生成的。这很棒,因为您的控制器可以专注于其实际工作,而不是如何实例化另一个对象。这一点在单一责任原则上越来越近。
依赖注入
然后,要利用第二个优点,构造函数应该接收接口而不是类。这就是所谓的依赖注入。
如果以后由于某种原因而决定以StudentRepository
任何方式更改您的类,只要您仍然实现该接口,就不必对控制器进行更改。
因此,您的最终代码可能类似于:
class HomeController
{
private IStudentRepository _repository;
public HomeController(IStudentRepository _repository)
{
//We don't know who instanciated the repo, but we don't care
this._repository = _repository;
}
public JsonResult Index()
{
//We only know about the repo that it implements IStudentRepository
//So we know we can call this method without a risk.
var m= _repository.getAll();
return Json(m,JsonRequestBehavior.AllowGet);
}
}
当它改变
为了说明更改,假设您首先要测试存储库,但是没有正确的数据库连接。因此,您决定使用文件,您的课程将像这样:
public class TestStudentRepository : IStudentRepository
{
private string MyDatabaseFilePath;
public object getAll()
{
//Load everything from my text file
}
}
好的,这将起作用。现在让我们说您已经与数据库建立了连接,但是该连接需要一些步骤才能使用getAll()方法。对于您的解决方案,您将必须在中执行初始化步骤HomeController
。
现在使用此模式,您可以执行以下操作:
public class StudentRepository : IStudentRepository
{
private string _connectionString;
public DatabaseStudentRepository(string ConnectionString)
{
_cOnnectionString= ConnectionString;
}
public object getAll()
{
//Load everything from my text file
}
}
然后,使用控制器来确保它正确实例化对象的是对象的角色。您的控制器没有任何变化。
工厂模式
最后一步是为您的StudentRepository创建一个工厂。实例化适当的回购是工厂的职责:
public static class StudentRepositoryFactory
{
public static IStudentRepository InstanciateRepo(bool FromDatabase)
{
if (FromDatabase)
{
return new DatabaseStudentFactory("ConnectionString To my server");
}
else
{
return new TestStudentRepository();
}
}
}
而现在,无论您需要以何种方式初始化仓库,这都是工厂的职责。使用存储库的一种方法getAll()是Controller的角色。