Я работаю над проектом, в котором у меня есть общий уровень сервиса и репозитория. Я использую Automapper для сопоставления DTO с моделями сущностей. Одна сущность может иметь один или несколько DTO. Моя проблема в том, как мне сообщить моему универсальному классу репозитория, какой 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);
}
Общая реализация репозитория
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 будет возвращен. Класс Contract был частью моего тестирования, но он не работает. Должен ли я использовать рефлексию, чтобы передать каждому методу в службе тип 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);
}
}
Большое спасибо заранее! И я надеюсь, что этот вопрос может помочь и другим людям!
Хороших выходных!
Лучано