Il livello di servizio è responsabile della mappatura (conversione) degli oggetti Dto e degli oggetti Dominio implementando l'appropriato business logic.
Gli oggetti DTO devono essere utilizzati in controller e servizi.
DTO vengono trasferite tra controllore e di servizio, sugli altri oggetti di dominio mano vengono trasferiti tra servizio e Repository
controllore non sapere di dominio e repository non conoscono DTO. Il servizio conosce DTO e Dominio e li converte reciprocamente con regole di business come un'automobile tra conducente e strada, come lo stackoverflow tra me e te, come tutto, l'astrazione ...
Il seguente codice è un esempio. Considera che ogni spazio dei nomi è un pacchetto.
namespace Controllers
{
using Services;
using DataTransferObjects;
public class CoffeeController
{
public ICoffeeService CoffeeService { get; set; }
public JsonResult GetCoffee(GetCoffeeInDto inDto)
{
var result = CoffeeService.GetCoffee(inDto);
return JsonResult(result);
}
public JsonResult SaveCoffee(SaveCoffeeInDto inDto)
{
var outDto = CoffeeService.SaveCoffee(inDto);
return JsonResult(outDto);
}
}
}
namespace Services
{
using DataTransferObjects;
public interface ICoffeeService
{
GetCoffeeOutDto GetCoffee(GetCoffeeInDto inDto);
SaveCoffeeOutDto SaveCoffee(SaveCoffeeInDto inDto);
}
}
namespace Services.Impl
{
using Services;
using Repository;
using DataTransferObjects;
using Domain;
public class CoffeeService : ICoffeeService
{
public ICoffeeRepository CoffeeRepository { get; set; }
public GetCoffeeOutDto GetCoffee(GetCoffeeInDto inDto)
{
var entity = CoffeeRepository.Get(inDto.Id);
return new GetCoffeeOutDto {Id = entity.Id, Name = entity.Name};
}
public SaveCoffeeOutDto SaveCoffee(SaveCoffeeInDto inDto)
{
var entity = new CoffeeEntity {Name = inDto.Name};
CoffeeRepository.Save(entity);
return new SaveCoffeeOutDto {Id = entity.Id};
}
}
}
namespace Repository
{
using Domain;
public interface ICoffeeRepository
{
CoffeeEntity Get(int id);
void Save(CoffeeEntity coffeeEntity);
}
}
namespace Repository.Impl
{
using Repository;
using Domain;
public class CoffeeRepository:ICoffeeRepository
{
public CoffeeEntity Get(int id)
{
//get entity from db
throw new System.NotImplementedException();
}
public void Save(CoffeeEntity coffeeEntity)
{
//insert entity into db
throw new System.NotImplementedException();
}
}
}
namespace DataTransferObjects
{
public class SaveCoffeeInDto
{
public string Name { get; set; }
}
public class SaveCoffeeOutDto
{
public int Id { get; set; }
}
public class GetCoffeeInDto
{
public int Id { get; set; }
}
public class GetCoffeeOutDto
{
public int Id { get; set; }
public string Name { get; set; }
}
}
namespace Domain
{
public class CoffeeEntity
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Se invii CoffeeEntity al controller anziché a GetCoffeeInDto, posso violare le regole dell'architettura? Mi sembra di riscrivere gli oggetti del dominio solo per utilizzare i DTO. – SherleyDev
Sì, se si invia un'entità al controller, si viola l'architettura. Ma non devi usare questa architettura, se il tuo progetto non è grande e la tua attività non è abbastanza complicata. La separazione di oggetti come Dto e Entity riguarda la distinzione tra informazioni e dati. Per quanto riguarda il principio della separazione delle preoccupazioni, giocare con i dati nel livello dati e giocare con le informazioni nel livello di presentazione sono considerati problemi separati e tenuti con l'uso di implementazioni di classi separate. – mecek
+1 Risposta eccellente. @ SherleyDev Dai un'occhiata qui: http://stackoverflow.com/a/21569720/654708 per una risposta più dettagliata. Nota, non è intrinsecamente male legare il tuo controller ai tuoi modelli di dominio; per i progetti più piccoli, la creazione di DTO potrebbe essere considerata eccessiva. – GFoley83