0
我在一個項目中工作,我有一個通用服務和存儲庫層。我使用Automapper將DTO映射到實體模型。一個實體可以有一個或多個DTO。我的問題是,如何告訴我的通用存儲庫類,哪個DTO應該返回到服務層?具有多個DTO到一個實體的通用存儲庫(Automapper)
實體
[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);
}
}
非常感謝!我希望這個問題也能幫助其他人!
週末愉快!
Luciano
現在你面臨着試圖以通用方式製造「一切」的後果。編程是關於上下文的,你首先分離一切,然後當你看到一些通用模式時,你將使用通用的方法。 – Fabio
感謝@Fabio爲您解答。我已經有了一些特定的存儲庫和服務來做一些特定的事情。我想用通用的做一些簡單的CRUD操作。如果我爲每個存儲庫構建一個findBy,我將爲每個實體使用完全相同的代碼,但具有不同的返回類型(不同的合同)。我想避免這種情況。謝謝! –
我不認爲如果你想在一個方法'getEntityContract'中做一個這樣做的方法,那麼這個方法應該知道返回的類型,無論是作爲參數還是頭部(無論你感覺如何),然後使用反射來執行使用通用執行的findBy。 也請改變URL名稱,就像每個REST一樣,URL應該看起來像「api/entities/byfilter」而不是「api/entity/getEntityByFilter」 如果你找到其他方法,請評論。 – Prince