public async Task<ClientMessage<bool>> DeleteAsync(string infrastructureName)
        {

            #region local parameters
            ClientMessage<bool> clientMessage = new ClientMessage<bool>();

            var infrastructure = await _context.Infrastructures.Include(t => t.CloudProvider)
                .Where(t => t.Name == infrastructureName && t.DeletedDate == null)
                .FirstOrDefaultAsync();
            #endregion local parameters

            #region validate infrastructure name
            if (infrastructure == null)
            {
                clientMessage.ClientStatusCode = AppEnums.OperationStatus.Error;
                clientMessage.ReturnedData = false;
                clientMessage.ClientMessageContent = new List<string> { "Error: infrastructure is not exist" };
                return clientMessage;
            }
            #endregion validate infrastructure name

            #region delete infrastructure on cloud service provider
            var serviceManager = new ServiceManager.ServiceManager();
            var igsProvider = new IGSCloudServices();
            serviceManager.DeleteInfrastructure += igsProvider.OnDeleteService;
            var deleted = serviceManager.Delete(infrastructure);

            if (!deleted)
            {
                clientMessage.ClientStatusCode = AppEnums.OperationStatus.Error;
                clientMessage.ClientMessageContent = new List<string> { "Error : an error occured while deleting infrastructure on provider" };
                return clientMessage;
            }
            #endregion region delete infrastructure on cloud service provider

            #region Mark infrastructure as deleted in database
            infrastructure.DeletedDate = DateTime.Now;
            infrastructure.DeletedById = -1; // -1 = system
            _context.SaveChanges();

            clientMessage.ClientStatusCode = AppEnums.OperationStatus.Ok;
            clientMessage.ReturnedData = true;
            return clientMessage;
            #endregion Mark infrastructure as deleted in database

        }
        public async Task<ClientMessage<int>> CreateAsync(InfrastructureUpsertDto postDto)
        {
            #region local parameters
            ClientMessage<int> clientMessage = new ClientMessage<int>();
            var dtoValidator = new InfrastructureUpsertValidator();
            #endregion local parameters

            #region validate payload
            var validationResult = dtoValidator.Validate(postDto);
            if (validationResult != null && validationResult.IsValid == false)
            {
                clientMessage.ClientStatusCode = AppEnums.OperationStatus.ValidationError;
                clientMessage.ValidationResults = validationResult.Errors.Select(modelError => new System.ComponentModel.DataAnnotations.ValidationResult(errorMessage: modelError.ErrorMessage)).ToList();
                return clientMessage;
            }
            #endregion validate payload

            #region Infrastructure already exists
            var alreadyExists = await _context.Infrastructures.Where(t => t.Name == postDto.Name && t.DeletedDate == null)
                .FirstOrDefaultAsync();
            if (alreadyExists != null)
            {
                clientMessage.ClientStatusCode = AppEnums.OperationStatus.ValidationError;
                clientMessage.ClientMessageContent = new List<string> { "Error : Infrastructure already exists" };
                return clientMessage;
            }
            #endregion Infrastructure already exists

            #region create infrastructure on cloud service provider
            var serviceManager = new ServiceManager.ServiceManager();
            var igsProvider = new IGSCloudServices();

            //now we need to notify cloud provider to make them create the infrastructure ,there are 2 methods
            //first method is to use reflection and query assembly and get all service providers then call create method like below
            //var allCloudProvider = typeof(CloudServices).Assembly.ExportedTypes.Where(t =>
            //        typeof(CloudServices).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract)
            //    .Select(Activator.CreateInstance).Cast<CloudServices>().ToList();
            //allCloudProvider.ForEach(t=>t.OnCreateService(/*method parameters goes here */));

            //second method is to fire event and make all provider subscribe to that event like below
            // all providers must subscribe 
            serviceManager.CreateInfrastructure += igsProvider.OnCreateService;
            var created = serviceManager.Create(postDto);

            if (!created)
            {
                clientMessage.ClientStatusCode = AppEnums.OperationStatus.Error;
                clientMessage.ClientMessageContent = new List<string> { "Error : an error occured while creating infrastructure on provider, or you used unsupported provider" };
                return clientMessage;
            }
            #endregion region create infrastructure on cloud service provider

            #region Add to database
            var infrastructure = _mapper.Map<Infrastructure>(postDto);
            await _context.Infrastructures.AddAsync(infrastructure);

            var effectedRows = _context.SaveChanges();
            if (effectedRows == 0)
            {
                clientMessage.ClientStatusCode = AppEnums.OperationStatus.Error;
                clientMessage.ClientMessageContent = new List<string> { "Error : an error occured while saving infrastructure details to database" };
                return clientMessage;
            }

            clientMessage.ClientStatusCode = AppEnums.OperationStatus.Ok;
            clientMessage.ReturnedData = infrastructure.Id;

            return clientMessage;
            #endregion Add to database


        }