나는 일반 서비스 및 저장소 계층이있는 프로젝트에서 작업하고 있습니다. Automapper를 사용하여 DTO를 엔티티 모델에 매핑합니다. 하나의 엔티티는 하나 이상의 DTO를 가질 수 있습니다. 내 문제는 어떻게 내 일반 저장소 클래스 DTO 서비스 계층에 반환해야 말해야합니까?하나의 엔터티 (Automapper)에 여러 DTO가있는 일반 저장소
엔티티
[Table("Entity")]
public class Entity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
[Required]
public string name { get; set; }
[Required]
public string surname { get; set; }
}
DTO들
public class Contract
{
}
[DataContract]
public class EntityContract: Contract
{
[Required]
[DataMember]
public string name { get; set; }
[Required]
[DataMember]
public string surname { get; set; }
}
[DataContract]
public class EntityPassportContract: Contract
{
[Required]
[DataMember]
public string name { get; set; }
[Required]
[DataMember]
public string surname { get; set; }
[Required]
[DataMember]
public string passport { get; set; }
}
일반 저장소
public interface IGenericRepository<E, DTO>
where E : class
where DTO: class
{
List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null);
}
창 neric 저장소 구현
public abstract class GenericRepository<C, E, DTO> : IGenericRepository<T, DTO>
where E : class
where DTO: class
where C : IdentityDbContext<User>, new()
{
//...
public virtual List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null)
{
//...transform DTO queries to E queries and Get IQueriable<E> entity from database
DTO dtoEntity=entity.ProjectTo<DTO>();
return dtoEntity;
}
}
일반 서비스
public interface IService<E, DTO> : IService
where T: class
where DTO: class
{
List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null);
}
일반 서비스 구현
public abstract class Service<E, DTO> : IService<T, DTO>
where E: class
where DTO: class
{
protected IGenericRepository<E, DTO> repository;
public Service(IGenericRepository<E, DTO> repository,)
{
this.repository = repository;
}
public virtual List<DTO> findBy(Expression<Func<DTO, bool>> query = null, Func<IQueryable<DTO>, IOrderedQueryable<DTO>> orderBy = null,
Expression<Func<DTO, bool>> whereIn = null, int? page = null, int? sizePage = null)
{
return repository.findBy(query, orderBy, whereIn, page, sizePage).ToList();
}
}
엔티티 저장소 및 서비스
,public interface IEntityRepository : IGenericRepository<Entity, Contract>
{
}
public class EntityRepository : GenericRepository<EntitiesDB, Entity, Contract>, IEntityRepository
{
public EntityRepository(IMapper mapper):base(mapper){ }
}
//Service
public interface IEntityService : IService<Entity, Contract>
{
}
public class EntityService : Service<Entity, Contract>, IEntityService
{
private IEntityRepository repo;
public EntityService(IEntityRepository repo) : base(repo)
{
this.repo = repo;
}
}
컨트롤러 나는 일반 서비스 방법 findBy를 호출하고 DTO 반환 할 것입니다 어떤 선택합니다. 계약 클래스는 테스트의 일부 였지만 작동하지 않습니다. 서비스의 각 메소드를 원하는 DTO 유형으로 전달할 수 있습니까?
[RoutePrefix("api/entity")]
public class EntityController : ApiController
{
public EntityController(IEntityService entityService)
: base(entityService)
{
}
[Route("getEntityByFilter", Name = "getEntityByFilter")]
[HttpGet]
public async Task<IHttpActionResult> getEntityContract(string filter)
{
EntityContract entityContract=entityService.findBy(**Parameters**); //Need to call lambda expressions here so i think i need somehow the type.
return Ok(entityContract);
}
[Route("getEntityByFilter2", Name = "getEntityByFilter2")]
[HttpGet]
public async Task<IHttpActionResult> getEntityPassportContract(string filter)
{
EntityPassportContract entityPassportContract=entityService.findBy(**Parameters**); //Need to call lambda expressions here so i think i need somehow the type.
return Ok(entityPassportContract);
}
}
미리 감사드립니다. 이 질문이 다른 사람들에게도 도움이되기를 바랍니다.
멋진 주말 보내십시오!
루치아노
이제 "모든 것"을 일반적인 방법으로 만들려고 할 때의 결과에 직면했습니다. 프로그래밍은 모두 컨텍스트에 관한 것입니다. 먼저 모든 것을 분리 한 다음 일반 패턴을 볼 때 일반적인 접근 방식을 적용합니다. – Fabio
답장을 보내 주셔서 감사합니다. @Fabio. 나는 이미 특정 자료를 가지고있는 특정 저장소와 서비스를 가지고있다. 몇 가지 간단한 CRUD 작업을 수행하기 위해 일반적인 것들을 사용하고 싶습니다. 각 저장소에 대해 findBy를 빌드하면 각 엔티티에 대해 동일한 코드를 갖지만 다른 반환 유형 (다른 계약)을 갖게됩니다. 나는 그 상황을 피하고 싶다. 감사! –
당신은 하나의 메소드 'getEntityContract'에서 수행하기를 원한다면 리플렉션없이이 작업을 수행 할 방법이 없을 것이라고 생각합니다. 그러면이 메소드는 매개 변수로 또는 헤더에서 리턴 할 유형에 대해 알아야합니다.), 리플렉션을 사용하여 일반 실행을 사용하여 findBy를 실행합니다. 또한 URL 이름을 변경하십시오. REST와 같이 URL은 "api/entities/byFilter"가 아닌 "api/entity/getEntityByFilter"가되어야합니다. 다른 방법을 찾으면 의견을 말하십시오. – Prince