[Authorize]
public class ContactController{
private readonly ContactService service;
public ContactController(ContactService service){
this.service = service;
}
public IActionResult Index() {
var model = service.GetContacts();
return View(model);
}
}
public class ContactService {
private readonly ContactRepository repository;
public ContactService(ContactRepository repository){
this.repository = repository;
}
public IEnumerable<ContactViewModel> GetContacts() {
var contacts = repository.GetAll();
return contacts.Select(c=> new ContactViewModel(c));
}
}
public class ContactRepository {
private readonly ApplicationDbContext db;
public ContactRepository(ApplicationDbContext context){
db = context;
}
public IQueryable<Contact> GetAll() {
return db.Contacts;
}
}
现在我想只获取经过身份验证的用户的联系人。假设联系人有一个UserId属性,所以, 我想做。哪里(c =&gt; c.UserId == userId)'某处';
假设代码在哪里?在服务?在存储库?在控制器?
服务的实现将是这样的:
public class ContactService {
private readonly ContactRepository repository;
private readonly IIdentity identity;
public ContactService(ContactRepository repository, HttpContext httpContext){
if (context?.User?.Identity?.IsAuthenticated == false)
throw new ArgumentException("Non authenticated request", nameof(httpContext));
identity = HttpContext.Current.User.Identity;
this.repository = repository;
}
public IEnumerable<ContactViewModel> GetContacts() {
var contacts = repository.GetAll()
.Where(c=> c.UserId == identity.GetUserId()); // <-- authorization logic.
return contacts.Select(c=> new ContactViewModel(c));
}
}
这是正确的做法吗? 你好吗?另一层?
答案 0 :(得分:0)
我会警告不要公开从您的存储库中暴露IQueryable。公开IQueryable意味着利用存储库的类确定何时将IQueryable实际解析为数据库往返。这意味着您的存储库难以使用,并且无法提供清晰的关注点分离。
出于这个原因,我在任何数据库存储库(如
)上使用了更具体的接口public Contact[] GetAllContacts() {}
public Contact GetContact(int userId) {}
返回像Lists和Arrays这样的混凝土而不是IQueryable会强制数据库在存储库中往返。权衡的是它更冗长,但值得分离它所提供的关注点。
[编辑]例如 - 数据库往返实际发生在上面的代码中?实际上,直到视图执行并实际从模型中读取数据才会发生。