public object CreateEntityAndFillFromDto(TDto dto, string methodCtorName) { if (!_entityInfo.CanBeCreatedByCtorOrStaticMethod && !_entityInfo.CanBeCreatedViaAutoMapper) { throw new InvalidOperationException($"I cannot create the entity class {_entityInfo.EntityType.Name} because it has no public constructor, or valid static creator methods."); } //we look for methods to create/update a new entity in the following order //1. A public static method that returns IStatusGeneric (chosing the one with the most parameters that the DTO has too) //2. A public parameterised constructor (chosing the one with the most parameters that the DTO has too) //3. By creating via parameterless ctor and then using AutoMapper to set the properties var decodedName = _dtoInfo.GetSpecifiedName(methodCtorName, CrudTypes.Create); if (_entityInfo.CanBeCreatedByCtorOrStaticMethod) { var ctorStaticToRun = _dtoInfo.GetCtorStaticCreatorToRun(decodedName, _entityInfo); var runStatus = BuildCall.RunMethodOrCtorViaLinq(ctorStaticToRun, dto, ctorStaticToRun.PropertiesMatch.MatchedPropertiesInOrder.ToList(), _context); CombineStatuses(runStatus); return(runStatus.Result); } if (_entityInfo.HasPublicParameterlessCtor && _entityInfo.CanBeUpdatedViaProperties) { var entityInstance = Activator.CreateInstance(_entityInfo.EntityType); var mapper = new CreateMapper(_context, _wrapperMapperConfigs, typeof(TDto), _entityInfo); mapper.Accessor.MapDtoToEntity(dto, entityInstance); return(entityInstance); } throw new InvalidOperationException( $"There was no way to create the entity class {_entityInfo.EntityType.Name} using {decodedName.ToString() ?? "any approach"}."); }
public async Task <IStatusGeneric> ReadEntityAndUpdateViaDtoAsync(TDto dto, string methodName) { //first we need to load it var keys = _context.GetKeysFromDtoInCorrectOrder(dto, _dtoInfo); var mapper = new CreateMapper(_context, _configAndMapper, typeof(TDto), _entityInfo); var entity = await mapper.Accessor.ReturnExistingEntityWithPossibleIncludesAsync(keys).ConfigureAwait(false); if (entity == null) { return(new StatusGenericHandler() .AddError( $"Sorry, I could not find the {_entityInfo.EntityType.GetNameForClass()} you were trying to update.")); } return(RunMethodViaLinq(dto, methodName, entity, mapper)); }
public IStatusGeneric ReadEntityAndUpdateViaDto(TDto dto, string methodName, params Expression <Func <TDto, object> >[] includes) { //first we need to load it var keys = _context.GetKeysFromDtoInCorrectOrder(dto, _dtoInfo); var mapper = new CreateMapper(_context, _configAndMapper, typeof(TDto), _entityInfo); var entity = mapper.Accessor.ReturnExistingEntity(keys, includes); if (entity == null) { return(new StatusGenericHandler() .AddError( $"Sorry, I could not find the {_entityInfo.EntityType.GetNameForClass()} you were trying to update.")); } //we look for methods to update a new entity in the following order //1. DDD-styled entity: A public access method that fits the DTO //2. Standard styled entity: using AutoMapper to update the entity var decodedName = _dtoInfo.GetSpecifiedName(methodName, CrudTypes.Update); if (_entityInfo.CanBeUpdatedViaMethods && decodedName.NameType != DecodedNameTypes.AutoMapper) { //1. DDD-styled entity: A public access method that fits the DTO //This gets one method to run. If it can't be found, or there are too many matches it throws an exception var methodToUse = _dtoInfo.GetMethodToRun(decodedName, _entityInfo); //This runs the method via LINQ return(BuildCall.RunMethodViaLinq(methodToUse.Method, dto, entity, methodToUse.PropertiesMatch.MatchedPropertiesInOrder.ToList(), _context, _createNewDBContext)); } if (_entityInfo.CanBeUpdatedViaProperties) { //2. Standard styled entity: using AutoMapper to update the entity mapper.Accessor.MapDtoToEntity(dto, entity); return(new StatusGenericHandler()); } throw new InvalidOperationException( $"There was no way to update the entity class {_entityInfo.EntityType.Name} using {decodedName.ToString() ?? "any approach"}."); }
/// <summary> /// This look for methods to update a new entity in the following order /// 1. DDD-styled entity: A public access method that fits the DTO /// 2. Standard styled entity: using AutoMapper to update the entity</summary> /// <param name="dto"></param> /// <param name="methodName"></param> /// <param name="entity"></param> /// <param name="mapper"></param> /// <returns></returns> private IStatusGeneric RunMethodViaLinq(TDto dto, string methodName, dynamic entity, CreateMapper mapper) { var decodedName = _dtoInfo.GetSpecifiedName(methodName, CrudTypes.Update); if (_entityInfo.CanBeUpdatedViaMethods && decodedName.NameType != DecodedNameTypes.AutoMapper) { //1. DDD-styled entity: A public access method that fits the DTO //This gets one method to run. If it can't be found, or there are too many matches it throws an exception var methodToUse = _dtoInfo.GetMethodToRun(decodedName, _entityInfo); //This runs the method via LINQ return(BuildCall.RunMethodViaLinq(methodToUse.Method, dto, entity, methodToUse.PropertiesMatch.MatchedPropertiesInOrder.ToList(), _context)); } if (_entityInfo.CanBeUpdatedViaProperties) { //2. Standard styled entity: using AutoMapper to update the entity mapper.Accessor.MapDtoToEntity(dto, entity); return(new StatusGenericHandler()); } throw new InvalidOperationException( $"There was no way to update the entity class {_entityInfo.EntityType.Name} using {decodedName.ToString() ?? "any approach"}."); }