什么是依賴
簡(jiǎn)單的理解就是,一個(gè)類A用到了另一個(gè)類B晃跺,這種使用關(guān)系是具有偶然性的,臨時(shí)性的毫玖,非常弱的掀虎,但是當(dāng)類B發(fā)生變化時(shí),又會(huì)影響到類A付枫。
舉個(gè)例子:
我們有一個(gè)Customer的Controller烹玉,它需要完成對(duì)Customer的查找或新增,如果我們用EF進(jìn)行數(shù)據(jù)庫操作的話阐滩,CustomerController就會(huì)對(duì)數(shù)據(jù)庫的Context有一個(gè)依賴的關(guān)系二打。
顯式依賴與隱式依賴
要解釋這個(gè)的話,還是看代碼比較直接掂榔。
[Route("customer")]
public class CustomerController:Controller
{
[HttpPost]
[Route("add")]
public IActionResult Add([FromBody]Model.Customer customer)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var context=new CustomerContext(new DBContextOptions<CustomerContext>{});
var result=context.Customers.SingleOrDefault(c=>c.Phone=customer.Phone);
if(result!=null)
{
return BadRequest(new {code=1001,message="手機(jī)號(hào)碼已存在"})继效;
}
context.Customers.Add(customer);
context.SaveChanges();
return Ok();
}
[HttpGet]
[Route("detail")]
public IActionResult Detail(int id)
{
var context=new CustomerContext(new DBContextOptions<CustomerContext>{});
var customer=context.Customers.SingleOrDefault(c=>c.Id=id);
if(result==null)
{
return NotFound();
}
return Json(customer);
}
}
這種代碼編寫方式是隱式依賴。
再來看:
[Route("customer")]
public class CustomerController:Controller
{
private CustomerContext _context;
public CustomerController()
{
_context=new CustomerContext(new DBContextOptions<CustomerContext>{});
}
[HttpPost]
[Route("add")]
public IActionResult Add([FromBody]Model.Customer customer)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result=_context.Customers.SingleOrDefault(c=>c.Phone=customer.Phone);
if(result!=null)
{
return BadRequest(new {code=1001,message="手機(jī)號(hào)碼已存在"})装获;
}
context.Customers.Add(customer);
context.SaveChanges();
return Ok();
}
[HttpGet]
[Route("detail")]
public IActionResult Detail(int id)
{
var customer=_context.Customers.SingleOrDefault(c=>c.Id=id);
if(result==null)
{
return NotFound();
}
return Json(customer);
}
}
這種就是顯式依賴瑞信。
依賴倒置
高層業(yè)務(wù)不依賴于低層業(yè)務(wù)的具體實(shí)現(xiàn),而依賴于具體的抽象穴豫。上面的UML圖可以修改如下:
將來凡简,如果不適用EF,而改用其他方式的話精肃,UML圖可改動(dòng)如下:
這就實(shí)現(xiàn)了依賴倒置秤涩,具體代碼如下:
[Route("customer")]
public class CustomerController:Controller
{
private ICustomerRepository _customerRepository;
public CustomerController()
{
_customerRepository=new EFCustomerRepository(new DBContextOptions<CustomerContext>{});
}
[HttpPost]
[Route("add")]
public IActionResult Add([FromBody]Model.Customer customer)
{
if(!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var result=_customerRepository.GetPhone(customer.Phone);
if(result!=null)
{
return BadRequest(new {code=1001,message="手機(jī)號(hào)碼已存在"});
}
_customerRepository.Insert(customer);
return Ok();
}
[HttpGet]
[Route("detail")]
public IActionResult Detail(int id)
{
var customer=_customerRepository.GetById(id);
if(result==null)
{
return NotFound();
}
return Json(customer);
}
}
控制反轉(zhuǎn)
將控制權(quán)交出去司抱,代碼如下:
private ICustomerRepository _customerRepository;
public CustomerController(ICustomerRepository customerRepository)
{
_customerRepository=customerRepository;
}
這樣筐眷,你既可以傳EFCustomerRepository,也可以傳MemoryCustomerRepository了习柠。