├── WebAPI ├── Program.cs ├── Images │ └── 23c5247d-cd08-49c2-ba16-275cbbc9a6ba_2_28_2021.jpg ├── appsettings.Development.json ├── WeatherForecast.cs ├── appsettings.json ├── WebAPI.csproj ├── Properties │ └── launchSettings.json ├── Controllers │ ├── WeatherForecastController.cs │ ├── AuthController.cs │ ├── UsersController.cs │ ├── ColorsController.cs │ ├── RentalsController.cs │ ├── BrandsController.cs │ ├── CustomersController.cs │ ├── CarsImagesController.cs │ └── CarsController.cs └── Startup.cs ├── images ├── folder.png └── rentalcar.jpg ├── Core ├── Entities │ ├── IDto.cs │ ├── IEntity.cs │ └── Concrete │ │ ├── OperationClaim.cs │ │ ├── UserOperationClaim.cs │ │ └── User.cs ├── Utilities │ ├── Results │ │ ├── IDataResult.cs │ │ ├── IResult.cs │ │ ├── ErrorResult.cs │ │ ├── SuccessResult.cs │ │ ├── Result.cs │ │ ├── DataResult.cs │ │ ├── SuccessDataResult.cs │ │ └── ErrorDataResult.cs │ ├── Security │ │ ├── JWT │ │ │ ├── AccessToken.cs │ │ │ ├── ITokenHelper.cs │ │ │ ├── TokenOptions.cs │ │ │ └── JwtHelper.cs │ │ ├── Encryption │ │ │ ├── SecurityKeyHelper.cs │ │ │ └── SigningCredentialsHelper.cs │ │ └── Hashing │ │ │ └── HashingHelper.cs │ ├── IoC │ │ ├── ICoreModule.cs │ │ └── ServiceTool.cs │ ├── Business │ │ └── BusinessRules.cs │ ├── Interceptors │ │ ├── MethodInterceptionBaseAttribute.cs │ │ ├── AspectInterceptorSelector.cs │ │ └── MethodInterception.cs │ └── Helpers │ │ └── FileHelper.cs ├── CrossCuttingConcerns │ ├── Caching │ │ ├── ICacheManager.cs │ │ └── Microsoft │ │ │ └── MemoryCacheManager.cs │ └── Validation │ │ └── ValidationTool.cs ├── Extensions │ ├── ServiceCollectionExtensions.cs │ ├── ClaimsPrincipalExtensions.cs │ └── ClaimExtensions.cs ├── DataAccess │ ├── IEntityRepository.cs │ └── EntityFramework │ │ └── EfEntityRepositoryBase.cs ├── Aspects │ └── Autofac │ │ ├── Caching │ │ ├── CacheRemoveAspect.cs │ │ └── CacheAspect.cs │ │ ├── Transaction │ │ └── TransactionScopeAspect.cs │ │ ├── Performance │ │ └── PerformanceAspect.cs │ │ └── Validation │ │ └── ValidationAspect.cs ├── DependencyResolvers │ └── CoreModule.cs └── Core.csproj ├── DataAccess ├── Abstract │ ├── IBrandDal.cs │ ├── IColorDal.cs │ ├── IUserDal.cs │ ├── ICarImageDal.cs │ ├── ICustomerDal.cs │ ├── IRentalDal.cs │ └── ICarDal.cs ├── DataAccess.csproj └── Concrete │ ├── EntityFramework │ ├── EfBrandDal.cs │ ├── EfColorDal.cs │ ├── EfCustomerDal.cs │ ├── RentACarContext.cs │ ├── EfUserDal.cs │ ├── EfCarImageDal.cs │ ├── EfRentalDal.cs │ └── EfCarDal.cs │ └── InMemory │ ├── InMemoryColorDal.cs │ ├── InMemoryBrandDal.cs │ └── InMemoryCarDal.cs ├── Entities ├── Concrete │ ├── Brand.cs │ ├── Color.cs │ ├── Customer.cs │ ├── CarImage.cs │ ├── Rental.cs │ └── Car.cs ├── DTOs │ ├── UserForLoginDto.cs │ ├── UserForRegisterDto.cs │ ├── CarDto.cs │ ├── CustomerDto.cs │ ├── CarImageDto.cs │ └── RentalDto.cs └── Entities.csproj ├── ConsoleUI ├── ConsoleUI.csproj └── Program.cs ├── Business ├── ValidationRules │ └── FluentValidation │ │ ├── CarImageValidator.cs │ │ ├── CustomerValidator.cs │ │ ├── BrandValidator.cs │ │ ├── ColorValidator.cs │ │ ├── RentalValidator.cs │ │ ├── CarValidator.cs │ │ └── UserValidator.cs ├── Abstract │ ├── IColorService.cs │ ├── IBrandService.cs │ ├── IAuthService.cs │ ├── ICustomerService.cs │ ├── IUserService.cs │ ├── IRentalService.cs │ ├── ICarImageService.cs │ └── ICarService.cs ├── Business.csproj ├── DependencyResolvers │ ├── Ninject │ │ └── NinjectBusinessModule.cs │ └── Autofac │ │ └── AutofacBusinessModule.cs ├── Constants │ └── Messages.cs ├── BusinessAspects │ └── Autofac │ │ └── SecuredOperation.cs └── Concrete │ ├── ColorManager.cs │ ├── CustomerManager.cs │ ├── UserManager.cs │ ├── BrandManager.cs │ ├── RentalManager.cs │ ├── AuthManager.cs │ ├── CarManager.cs │ └── CarImageManager.cs ├── .gitattributes ├── ReCapProject.sln ├── README.md └── .gitignore /WebAPI/Program.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kadirdemirel/ReCapProject/HEAD/WebAPI/Program.cs -------------------------------------------------------------------------------- /images/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kadirdemirel/ReCapProject/HEAD/images/folder.png -------------------------------------------------------------------------------- /images/rentalcar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kadirdemirel/ReCapProject/HEAD/images/rentalcar.jpg -------------------------------------------------------------------------------- /WebAPI/Images/23c5247d-cd08-49c2-ba16-275cbbc9a6ba_2_28_2021.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kadirdemirel/ReCapProject/HEAD/WebAPI/Images/23c5247d-cd08-49c2-ba16-275cbbc9a6ba_2_28_2021.jpg -------------------------------------------------------------------------------- /Core/Entities/IDto.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Entities 6 | { 7 | public interface IDto 8 | { 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Core/Entities/IEntity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Entities 6 | { 7 | public interface IEntity 8 | { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /WebAPI/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Core/Entities/Concrete/OperationClaim.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | 3 | namespace Entities.Concrete 4 | { 5 | public class OperationClaim:IEntity 6 | { 7 | public int Id { get; set; } 8 | public string Name { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Core/Utilities/Results/IDataResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public interface IDataResult:IResult 8 | { 9 | T Data { get; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Core/Utilities/Results/IResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public interface IResult 8 | { 9 | bool Success { get; } 10 | string Message { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /DataAccess/Abstract/IBrandDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DataAccess.Abstract 8 | { 9 | public interface IBrandDal:IEntityRepository 10 | { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /DataAccess/Abstract/IColorDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DataAccess.Abstract 8 | { 9 | public interface IColorDal:IEntityRepository 10 | { 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Core/Entities/Concrete/UserOperationClaim.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | 3 | namespace Entities.Concrete 4 | { 5 | public class UserOperationClaim:IEntity 6 | { 7 | public int Id { get; set; } 8 | public int UserId { get; set; } 9 | public int OperationClaimId { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Entities/Concrete/Brand.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | public class Brand:IEntity 9 | { 10 | public int Id { get; set; } 11 | public string BrandName { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Entities/Concrete/Color.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | 9 | public class Color:IEntity 10 | { 11 | public int Id { get; set; } 12 | public string ColorName { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Core/Utilities/Security/JWT/AccessToken.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Security.JWT 6 | { 7 | public class AccessToken 8 | { 9 | public string Token { get; set; } 10 | public DateTime Expiration { get; set; } 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Entities/DTOs/UserForLoginDto.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.DTOs 7 | { 8 | public class UserForLoginDto : IDto 9 | { 10 | public string Email { get; set; } 11 | public string Password { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /DataAccess/Abstract/IUserDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DataAccess.Abstract 8 | { 9 | public interface IUserDal:IEntityRepository 10 | { 11 | List GetClaims(User user); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Core/Utilities/Security/JWT/ITokenHelper.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.Utilities.Security.JWT 7 | { 8 | public interface ITokenHelper 9 | { 10 | AccessToken CreateToken(User user, List operationClaims); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Entities/DTOs/UserForRegisterDto.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | 3 | namespace Entities.DTOs 4 | { 5 | public class UserForRegisterDto : IDto 6 | { 7 | public string Email { get; set; } 8 | public string Password { get; set; } 9 | public string FirstName { get; set; } 10 | public string LastName { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Entities/Entities.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /WebAPI/WeatherForecast.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WebAPI 4 | { 5 | public class WeatherForecast 6 | { 7 | public DateTime Date { get; set; } 8 | 9 | public int TemperatureC { get; set; } 10 | 11 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 12 | 13 | public string Summary { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Core/Utilities/IoC/ICoreModule.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.Utilities.IoC 7 | { 8 | public interface ICoreModule 9 | { 10 | //Bağımlılıklarımızı yükleyecek. 11 | void Load(IServiceCollection serviceCollection); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Entities/Concrete/Customer.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | public class Customer:IEntity 9 | { 10 | public int Id { get; set; } 11 | public int UserId { get; set; } 12 | public string CompanyName { get; set; } 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /DataAccess/Abstract/ICarImageDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess; 2 | using Entities.Concrete; 3 | using Entities.DTOs; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace DataAccess.Abstract 9 | { 10 | public interface ICarImageDal : IEntityRepository 11 | { 12 | List GetCarImageDetails(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /DataAccess/Abstract/ICustomerDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess; 2 | using Entities.Concrete; 3 | using Entities.DTOs; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace DataAccess.Abstract 9 | { 10 | public interface ICustomerDal:IEntityRepository 11 | { 12 | List GetCustomerDetails(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /DataAccess/Abstract/IRentalDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess; 2 | using Entities.Concrete; 3 | using Entities.DTOs; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace DataAccess.Abstract 9 | { 10 | public interface IRentalDal:IEntityRepository 11 | { 12 | List GetRentalDetails(); 13 | 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Core/Utilities/Results/ErrorResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public class ErrorResult:Result 8 | { 9 | public ErrorResult(string message):base(false,message) 10 | { 11 | 12 | } 13 | public ErrorResult():base(false) 14 | { 15 | 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DataAccess/Abstract/ICarDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace DataAccess.Abstract 8 | { 9 | public interface ICarDal:IEntityRepository 10 | { 11 | List GetCarDetails(); 12 | List GetCarAsc(); 13 | List GetCarDesc(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Entities/Concrete/CarImage.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | public class CarImage : IEntity 9 | { 10 | public int Id { get; set; } 11 | public int CarId { get; set; } 12 | public string ImagePath { get; set; } 13 | public DateTime Date { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Core/Utilities/Results/SuccessResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public class SuccessResult : Result 8 | { 9 | public SuccessResult(string message):base(true,message) 10 | { 11 | 12 | } 13 | public SuccessResult():base(true) 14 | { 15 | 16 | } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Core/Utilities/Security/JWT/TokenOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Security.JWT 6 | { 7 | public class TokenOptions 8 | { 9 | public string Audience { get; set; } 10 | public string Issuer { get; set; } 11 | public int AccessTokenExpiration { get; set; } 12 | public string SecurityKey { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /DataAccess/DataAccess.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /WebAPI/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "TokenOptions": { 3 | "Audience": "kadir@kadir.com", 4 | "Issuer": "kadir@kadir.com", 5 | "AccessTokenExpiration": 10, 6 | "SecurityKey": "mysupersecretkeymysupersecretkey" 7 | }, 8 | "Logging": { 9 | "LogLevel": { 10 | "Default": "Information", 11 | "Microsoft": "Warning", 12 | "Microsoft.Hosting.Lifetime": "Information" 13 | } 14 | }, 15 | "AllowedHosts": "*" 16 | } 17 | -------------------------------------------------------------------------------- /ConsoleUI/ConsoleUI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp3.1 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/EfBrandDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess.EntityFramework; 2 | using DataAccess.Abstract; 3 | using Entities.Concrete; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | using System.Text; 9 | 10 | namespace DataAccess.Concrete.EntityFramework 11 | { 12 | public class EfBrandDal :EfEntityRepositoryBase,IBrandDal 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/EfColorDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess.EntityFramework; 2 | using DataAccess.Abstract; 3 | using Entities.Concrete; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | using System.Text; 9 | 10 | namespace DataAccess.Concrete.EntityFramework 11 | { 12 | public class EfColorDal : EfEntityRepositoryBase,IColorDal 13 | { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Entities/Concrete/Rental.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | public class Rental:IEntity 9 | { 10 | public int Id { get; set; } 11 | public int CarId { get; set; } 12 | public int CustomerId { get; set; } 13 | public DateTime RentDate { get; set; } 14 | public DateTime ReturnDate { get; set; } 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Business/ValidationRules/FluentValidation/CarImageValidator.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.ValidationRules.FluentValidation 8 | { 9 | public class CarImageValidator:AbstractValidator 10 | { 11 | public CarImageValidator() 12 | { 13 | RuleFor(p => p.Date).NotEmpty(); 14 | 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Business/Abstract/IColorService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.Abstract 8 | { 9 | public interface IColorService 10 | { 11 | IDataResult> GetAll(); 12 | IResult Add(Color color); 13 | IResult Update(Color color); 14 | IResult Delete(Color color); 15 | IDataResult GetById(int colorId); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Business/Abstract/IBrandService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.Abstract 8 | { 9 | public interface IBrandService 10 | { 11 | IDataResult> GetAll(); 12 | IResult Add(Brand brand); 13 | IResult Update(Brand brand); 14 | IResult Delete(Brand brand); 15 | IDataResult GetById(int brandId); 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Core/CrossCuttingConcerns/Caching/ICacheManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.CrossCuttingConcerns.Caching 6 | { 7 | public interface ICacheManager 8 | { 9 | T Get(string key); 10 | object Get(string key); 11 | void Add(string key,object value,int duration); 12 | bool IsAdd(string key); 13 | void Remove(string key); 14 | void RemoveByPattern(string pattern); 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Entities/Concrete/Car.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | public class Car : IEntity 9 | { 10 | public int Id { get; set; } 11 | public int BrandId { get; set; } 12 | public int ColorId { get; set; } 13 | public string ModelYear { get; set; } 14 | public int DailyPrice { get; set; } 15 | public string Description { get; set; } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Entities/DTOs/CarDto.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | public class CarDto:IDto 9 | { 10 | public int Id { get; set; } 11 | public string BrandName { get; set; } 12 | public string ColorName { get; set; } 13 | public string ModelYear { get; set; } 14 | public int DailyPrice { get; set; } 15 | public string Description { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Entities/DTOs/CustomerDto.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.DTOs 7 | { 8 | public class CustomerDto:IDto 9 | { 10 | public int Id { get; set; } 11 | public string CompanyName { get; set; } 12 | public string FirstName { get; set; } 13 | public string LastName { get; set; } 14 | public string Email { get; set; } 15 | public string Password { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Core/Utilities/Security/Encryption/SecurityKeyHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.IdentityModel.Tokens; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.Utilities.Security.Encryption 7 | { 8 | //SecurityKey oluşturmaya yarıyor. 9 | public class SecurityKeyHelper 10 | { 11 | public static SecurityKey CreateSecurityKey(string securityKey) 12 | { 13 | return new SymmetricSecurityKey(Encoding.UTF8.GetBytes(securityKey)); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Business/ValidationRules/FluentValidation/CustomerValidator.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.ValidationRules.FluentValidation 8 | { 9 | public class CustomerValidator:AbstractValidator 10 | { 11 | //Customer sınıfına özel doğrulama kuralları. 12 | public CustomerValidator() 13 | { 14 | RuleFor(p => p.CompanyName).NotEmpty(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Business/Abstract/IAuthService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Core.Utilities.Security.JWT; 3 | using Entities.Concrete; 4 | using Entities.DTOs; 5 | 6 | namespace Business.Abstract 7 | { 8 | public interface IAuthService 9 | { 10 | IDataResult Register(UserForRegisterDto userForRegisterDto, string password); 11 | IDataResult Login(UserForLoginDto userForLoginDto); 12 | IResult UserExists(string email); 13 | IDataResult CreateAccessToken(User user); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Core/Utilities/Results/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public class Result : IResult 8 | { 9 | public Result(bool success,string message):this(success) 10 | { 11 | Message = message; 12 | } 13 | public Result(bool success) 14 | { 15 | Success = success; 16 | } 17 | public bool Success { get; } 18 | 19 | public string Message { get; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Business/Abstract/ICustomerService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Entities.Concrete; 3 | using Entities.DTOs; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Business.Abstract 9 | { 10 | public interface ICustomerService 11 | { 12 | IResult Add(Customer customer); 13 | IResult Delete(Customer customer); 14 | IResult Update(Customer customer); 15 | IDataResult> GetAll(); 16 | IDataResult> GetCustomerDetails(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Business/Abstract/IUserService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.Abstract 8 | { 9 | public interface IUserService 10 | { 11 | IResult Add(User user); 12 | IResult Delete(User user); 13 | IResult Update(User user); 14 | IDataResult> GetAll(); 15 | IDataResult> GetClaims(User user); 16 | IDataResult GetByMail(string email); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Core/Utilities/IoC/ServiceTool.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.Utilities.IoC 7 | { 8 | public static class ServiceTool 9 | { 10 | public static IServiceProvider ServiceProvider { get; private set; } 11 | 12 | public static IServiceCollection Create(IServiceCollection services) 13 | { 14 | ServiceProvider = services.BuildServiceProvider(); 15 | return services; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Core/Utilities/Results/DataResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public class DataResult : Result, IDataResult 8 | { 9 | public DataResult(T data,bool success,string messsage):base(success,messsage) 10 | { 11 | Data = data; 12 | } 13 | public DataResult(T data,bool success):base(success) 14 | { 15 | Data = data; 16 | } 17 | public T Data { get; } 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Business/ValidationRules/FluentValidation/BrandValidator.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.ValidationRules.FluentValidation 8 | { 9 | public class BrandValidator:AbstractValidator 10 | { 11 | //Brand sınıfına özel doğrulama kuralları. 12 | public BrandValidator() 13 | { 14 | RuleFor(p => p.BrandName).NotEmpty(); 15 | RuleFor(p => p.BrandName).MinimumLength(2); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Business/ValidationRules/FluentValidation/ColorValidator.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.ValidationRules.FluentValidation 8 | { 9 | public class ColorValidator:AbstractValidator 10 | { 11 | //Color sınıfına özel doğrulama kuralları. 12 | public ColorValidator() 13 | { 14 | RuleFor(p => p.ColorName).NotEmpty(); 15 | RuleFor(p => p.ColorName).MinimumLength(2); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Business/ValidationRules/FluentValidation/RentalValidator.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.ValidationRules.FluentValidation 8 | { 9 | public class RentalValidator:AbstractValidator 10 | { 11 | //Rental sınıfına özel doğrulama kuralları. 12 | public RentalValidator() 13 | { 14 | RuleFor(p => p.RentDate).NotEmpty(); 15 | RuleFor(p => p.ReturnDate).NotEmpty(); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Core/Entities/Concrete/User.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.Concrete 7 | { 8 | public class User : IEntity 9 | { 10 | public int Id { get; set; } 11 | public string FirstName { get; set; } 12 | public string LastName { get; set; } 13 | public string Email { get; set; } 14 | public byte[] PasswordHash { get; set; } 15 | public byte[] PasswordSalt { get; set; } 16 | public bool Status { get; set; } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Business/Abstract/IRentalService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Entities.Concrete; 3 | using Entities.DTOs; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Business.Abstract 9 | { 10 | public interface IRentalService 11 | { 12 | IResult Add(Rental rental); 13 | IResult Delete(Rental rental); 14 | IResult Update(Rental rental); 15 | IDataResult> GetAll(); 16 | IDataResult> GetRentalDetails(); 17 | IDataResult GetById(int carId); 18 | 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Entities/DTOs/CarImageDto.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Entities.DTOs 7 | { 8 | public class CarImageDto : IDto 9 | { 10 | public int Id { get; set; } 11 | public string BrandName { get; set; } 12 | public string ColorName { get; set; } 13 | public string ModelYear { get; set; } 14 | public int DailyPrice { get; set; } 15 | public string Description { get; set; } 16 | public string ImagePath { get; set; } 17 | public DateTime Date { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Core/Utilities/Security/Encryption/SigningCredentialsHelper.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.IdentityModel.Tokens; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.Utilities.Security.Encryption 7 | { 8 | //App.netin de sistemi anlaması için hangi anahtar ve hangi doğrulama algoritması kullanacağını gösteriyoruz. 9 | public class SigningCredentialsHelper 10 | { 11 | public static SigningCredentials CreateSigningCredentials(SecurityKey securityKey) 12 | { 13 | return new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha512); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Core/CrossCuttingConcerns/Validation/ValidationTool.cs: -------------------------------------------------------------------------------- 1 | using FluentValidation; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.CrossCuttingConcerns.Validation 7 | { 8 | public static class ValidationTool 9 | { 10 | public static void Validate(IValidator validater, object entity) 11 | { 12 | var context = new ValidationContext(entity); 13 | var result = validater.Validate(context); 14 | if (!result.IsValid) 15 | { 16 | throw new ValidationException(result.Errors); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Core/Utilities/Results/SuccessDataResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public class SuccessDataResult:DataResult 8 | { 9 | public SuccessDataResult(T data,string message):base(data,true,message) 10 | { 11 | 12 | } 13 | public SuccessDataResult(T data):base(data,true) 14 | { 15 | 16 | } 17 | public SuccessDataResult(string message):base(default,true,message) 18 | { 19 | 20 | } 21 | public SuccessDataResult():base(default,true) 22 | { 23 | 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Core/Utilities/Results/ErrorDataResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Core.Utilities.Results 6 | { 7 | public class ErrorDataResult:DataResult 8 | { 9 | public ErrorDataResult(T data, string message) : base(data, false, message) 10 | { 11 | 12 | } 13 | public ErrorDataResult(T data) : base(data, false) 14 | { 15 | 16 | } 17 | public ErrorDataResult(string message) : base(default, false, message) 18 | { 19 | 20 | } 21 | public ErrorDataResult() : base(default, false) 22 | { 23 | 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Business/ValidationRules/FluentValidation/CarValidator.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.ValidationRules.FluentValidation 8 | { 9 | public class CarValidator : AbstractValidator 10 | { 11 | //Car sınıfına özel doğrulama kuralları. 12 | public CarValidator() 13 | { 14 | RuleFor(p => p.DailyPrice).NotEmpty(); 15 | RuleFor(p => p.DailyPrice).GreaterThan(0); 16 | RuleFor(p => p.ModelYear).NotEmpty(); 17 | RuleFor(p => p.Description).NotEmpty(); 18 | 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Core/Extensions/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.IoC; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Core.Extensions 8 | { 9 | public static class ServiceCollectionExtensions 10 | { 11 | public static IServiceCollection AddDependencyResolvers(this IServiceCollection serviceCollection,ICoreModule[] modules) 12 | { 13 | foreach (var module in modules) 14 | { 15 | module.Load(serviceCollection); 16 | } 17 | return ServiceTool.Create(serviceCollection); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Core/DataAccess/IEntityRepository.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq.Expressions; 5 | using System.Text; 6 | 7 | namespace Core.DataAccess 8 | { 9 | //Generic kısıtlama yaptık 10 | //referans tip almasını,IEntity veya IEntity'den türüyen nesneler alabildiğini 11 | //Vede new'lenebilir olan bir nesne alabildiğini yazdık 12 | public interface IEntityRepository where T : class, IEntity, new() 13 | { 14 | void Add(T entity); 15 | void Delete(T entity); 16 | void Update(T entity); 17 | List GetAll(Expression> filter = null); 18 | T Get(Expression> filter); 19 | 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Core/Extensions/ClaimsPrincipalExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Claims; 5 | using System.Text; 6 | 7 | namespace Core.Extensions 8 | { 9 | public static class ClaimsPrincipalExtensions 10 | { 11 | public static List Claims(this ClaimsPrincipal claimsPrincipal, string claimType) 12 | { 13 | var result = claimsPrincipal?.FindAll(claimType)?.Select(x => x.Value).ToList(); 14 | return result; 15 | } 16 | 17 | public static List ClaimRoles(this ClaimsPrincipal claimsPrincipal) 18 | { 19 | return claimsPrincipal?.Claims(ClaimTypes.Role); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Business/Abstract/ICarImageService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Entities.Concrete; 3 | using Entities.DTOs; 4 | using Microsoft.AspNetCore.Http; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | 9 | namespace Business.Abstract 10 | { 11 | public interface ICarImageService 12 | { 13 | IDataResult> GetAll(); 14 | IResult Add(IFormFile file, CarImage carImage); 15 | IResult Update(IFormFile file, CarImage carImage); 16 | IResult Delete(CarImage carImage); 17 | IDataResult Get(int carImageId); 18 | IDataResult> GetCarImageDetails(); 19 | IDataResult> GetImagesByCarId(int id); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Core/Utilities/Business/BusinessRules.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.Utilities.Business 7 | { 8 | public class BusinessRules 9 | { 10 | //params ile iş kurallarını bir diziye aktarıp bütün kuralları tek tek parametre olarak kurallarımızı geçebiliriz. 11 | //Bütün kurallar gezilip kuralama uymayan varsa o kural döndürülür. 12 | public static IResult Run(params IResult[] logics) 13 | { 14 | foreach (var logic in logics) 15 | { 16 | if (!logic.Success) 17 | { 18 | return logic; 19 | } 20 | } 21 | return null; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Entities/DTOs/RentalDto.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Entities.DTOs 8 | { 9 | public class RentalDto:IDto 10 | { 11 | public int Id { get; set; } 12 | public string BrandName { get; set; } 13 | public string ColorName { get; set; } 14 | public string ModelYear { get; set; } 15 | public int DailyPrice { get; set; } 16 | public string Description { get; set; } 17 | public string FirstName { get; set; } 18 | public string LastName { get; set; } 19 | public DateTime RentDate { get; set; } 20 | public DateTime ReturnDate { get; set; } 21 | public string CompanyName { get; set; } 22 | 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /WebAPI/WebAPI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp3.1 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Business/ValidationRules/FluentValidation/UserValidator.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using FluentValidation; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.ValidationRules.FluentValidation 8 | { 9 | public class UserValidator : AbstractValidator 10 | { 11 | //User sınıfına özel doğrulama kuralları. 12 | public UserValidator() 13 | { 14 | RuleFor(p => p.FirstName).NotEmpty(); 15 | RuleFor(p => p.FirstName).MinimumLength(3); 16 | RuleFor(p => p.LastName).NotEmpty(); 17 | RuleFor(p => p.LastName).MinimumLength(2); 18 | RuleFor(p => p.Email).NotEmpty(); 19 | RuleFor(p => p.PasswordHash.ToString()).NotEmpty(); 20 | RuleFor(p => p.PasswordHash.ToString()).MinimumLength(4); 21 | 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Business/Abstract/ICarService.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Business.Abstract 8 | { 9 | public interface ICarService 10 | { 11 | IDataResult> GetAll(); 12 | IDataResult GetById(int carId); 13 | IResult Add(Car car); 14 | IResult Delete(Car car); 15 | IResult Update(Car car); 16 | IDataResult> GetCarsByBrandId(int id); 17 | IDataResult> GetCarsByColorId(int id); 18 | IDataResult> GetByDailyPrice(decimal min, decimal max); 19 | IDataResult> GetCarDetails(); 20 | IDataResult> GetCarDesc(); 21 | IDataResult> GetCarAsc(); 22 | IResult AddTransactionalTest(Car car); 23 | 24 | 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Core/Aspects/Autofac/Caching/CacheRemoveAspect.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using Core.CrossCuttingConcerns.Caching; 3 | using Core.Utilities.Interceptors; 4 | using Core.Utilities.IoC; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace Core.Aspects.Autofac.Caching 11 | { 12 | public class CacheRemoveAspect : MethodInterception 13 | { 14 | private string _pattern; 15 | private ICacheManager _cacheManager; 16 | 17 | public CacheRemoveAspect(string pattern) 18 | { 19 | _pattern = pattern; 20 | _cacheManager = ServiceTool.ServiceProvider.GetService(); 21 | } 22 | 23 | protected override void OnSuccess(IInvocation invocation) 24 | { 25 | _cacheManager.RemoveByPattern(_pattern); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /WebAPI/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:51250", 8 | "sslPort": 44364 9 | } 10 | }, 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "weatherforecast", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "WebAPI": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "weatherforecast", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Business/Business.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Core/DependencyResolvers/CoreModule.cs: -------------------------------------------------------------------------------- 1 | using Core.CrossCuttingConcerns.Caching; 2 | using Core.CrossCuttingConcerns.Caching.Microsoft; 3 | using Core.Utilities.IoC; 4 | using Microsoft.AspNetCore.Http; 5 | using Microsoft.Extensions.DependencyInjection; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Diagnostics; 9 | using System.Text; 10 | 11 | namespace Core.DependencyResolvers 12 | { 13 | public class CoreModule : ICoreModule 14 | { 15 | //servis bağımlılıklarımızı çözümleyeceğimiz yer. 16 | public void Load(IServiceCollection serviceCollection) 17 | { 18 | serviceCollection.AddMemoryCache();//Arka planda instance oluşturuyor. 19 | serviceCollection.AddSingleton(); 20 | serviceCollection.AddSingleton(); 21 | serviceCollection.AddSingleton(); 22 | 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Core/Utilities/Interceptors/MethodInterceptionBaseAttribute.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Core.Utilities.Interceptors 7 | { 8 | //Burası ise başlangıç diyebileceğimiz kısım. 9 | //Sınıf veya method'lara Attribute ekleyebiliriz birden fazla Attribute kullanılabiliriz, Inherited edilen bir yerde kullanabiliriz. 10 | //Birden fazladan kasıt Loglama işlemini düşünecek olursak farklı parametreler kullanarak 2 farklı yerde kullanılabilir. 11 | [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)] 12 | public abstract class MethodInterceptionBaseAttribute : Attribute, IInterceptor 13 | { 14 | //Öncelik vermek için oluşturduğumuz property. 15 | public int Priority { get; set; } 16 | 17 | public virtual void Intercept(IInvocation invocation) 18 | { 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Core/Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/EfCustomerDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess.EntityFramework; 2 | using DataAccess.Abstract; 3 | using Entities.Concrete; 4 | using Entities.DTOs; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Linq; 9 | 10 | namespace DataAccess.Concrete.EntityFramework 11 | { 12 | public class EfCustomerDal : EfEntityRepositoryBase, ICustomerDal 13 | { 14 | public List GetCustomerDetails() 15 | { 16 | using (RentACarContext context = new RentACarContext()) 17 | { 18 | var result = from c in context.Customers 19 | join u in context.Users on c.UserId equals u.Id 20 | select new CustomerDto { Id = c.Id, FirstName = u.FirstName, LastName = u.LastName, Email = u.Email, Password = u.PasswordHash.ToString(), CompanyName = c.CompanyName }; 21 | return result.ToList(); 22 | 23 | 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Core/Utilities/Interceptors/AspectInterceptorSelector.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using System; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | namespace Core.Utilities.Interceptors 7 | { 8 | public class AspectInterceptorSelector : IInterceptorSelector 9 | { 10 | 11 | public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors) 12 | { 13 | //Sınıflardaki Attribute'leri okuyup listeliyor. 14 | var classAttributes = type.GetCustomAttributes 15 | (true).ToList(); 16 | //Methodlardaki Attribute'leri okuyor. 17 | var methodAttributes = type.GetMethod(method.Name) 18 | .GetCustomAttributes(true); 19 | classAttributes.AddRange(methodAttributes); 20 | 21 | //Öncelik değerine göre o Attributeleri çalıştırıyor. 22 | return classAttributes.OrderBy(x => x.Priority).ToArray(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/RentACarContext.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using Microsoft.EntityFrameworkCore; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | 8 | namespace DataAccess.Concrete.EntityFramework 9 | { 10 | public class RentACarContext : DbContext 11 | { 12 | protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) 13 | { 14 | optionsBuilder.UseSqlServer(@"Server=(localdb)\MSSQLLocalDB;Database=RentACar;Trusted_Connection=true"); 15 | } 16 | public DbSet Cars { get; set; } 17 | public DbSet Brands { get; set; } 18 | public DbSet Colors { get; set; } 19 | public DbSet Customers { get; set; } 20 | public DbSet Users { get; set; } 21 | public DbSet Rentals { get; set; } 22 | public DbSet CarImages { get; set; } 23 | public DbSet OperationClaims { get; set; } 24 | public DbSet UserOperationClaims { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Core/Extensions/ClaimExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IdentityModel.Tokens.Jwt; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Text; 7 | 8 | namespace Core.Extensions 9 | { 10 | public static class ClaimExtensions 11 | { 12 | public static void AddEmail(this ICollection claims, string email) 13 | { 14 | claims.Add(new Claim(JwtRegisteredClaimNames.Email, email)); 15 | } 16 | 17 | public static void AddName(this ICollection claims, string name) 18 | { 19 | claims.Add(new Claim(ClaimTypes.Name, name)); 20 | } 21 | 22 | public static void AddNameIdentifier(this ICollection claims, string nameIdentifier) 23 | { 24 | claims.Add(new Claim(ClaimTypes.NameIdentifier, nameIdentifier)); 25 | } 26 | 27 | public static void AddRoles(this ICollection claims, string[] roles) 28 | { 29 | roles.ToList().ForEach(role => claims.Add(new Claim(ClaimTypes.Role, role))); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/EfUserDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess.EntityFramework; 2 | using DataAccess.Abstract; 3 | using Entities.Concrete; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Linq; 8 | 9 | namespace DataAccess.Concrete.EntityFramework 10 | { 11 | public class EfUserDal : EfEntityRepositoryBase, IUserDal 12 | { 13 | 14 | public List GetClaims(User user) 15 | { 16 | using (var context = new RentACarContext()) 17 | { 18 | var result = from operationClaim in context.OperationClaims 19 | join userOperationClaim in context.UserOperationClaims 20 | on operationClaim.Id equals userOperationClaim.OperationClaimId 21 | where userOperationClaim.UserId == user.Id 22 | select new OperationClaim { Id = operationClaim.Id, Name = operationClaim.Name }; 23 | return result.ToList(); 24 | 25 | } 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Core/Aspects/Autofac/Transaction/TransactionScopeAspect.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using Core.Utilities.Interceptors; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Transactions; 7 | 8 | namespace Core.Aspects.Autofac.Transaction 9 | { 10 | public class TransactionScopeAspect : MethodInterception 11 | { 12 | //Invocation metot demek. 13 | public override void Intercept(IInvocation invocation) 14 | { 15 | //Şablon oluşturuyoruz. 16 | //Transaction yönetimi projedeki tutarlılığı sağlar. 17 | //Örneğin bir hesaptan diğerine para gönderilmesi. 18 | using (TransactionScope transactionScope = new TransactionScope()) 19 | { 20 | try 21 | { 22 | invocation.Proceed();//Method içindeki bloğu komple çalıştırır. 23 | transactionScope.Complete(); 24 | } 25 | catch (System.Exception e) 26 | { 27 | transactionScope.Dispose(); 28 | throw; 29 | } 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Business/DependencyResolvers/Ninject/NinjectBusinessModule.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.Concrete; 3 | using DataAccess.Abstract; 4 | using DataAccess.Concrete.EntityFramework; 5 | using Ninject.Modules; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Text; 9 | 10 | namespace Business.DependencyResolvers.Ninject 11 | { 12 | public class NinjectBusinessModule : NinjectModule 13 | { 14 | //Autofac yerine Ninject kullanmak istersek. 15 | public override void Load() 16 | { 17 | Bind().To(); 18 | Bind().To(); 19 | Bind().To(); 20 | Bind().To(); 21 | Bind().To(); 22 | Bind().To(); 23 | Bind().To(); 24 | Bind().To(); 25 | Bind().To(); 26 | Bind().To(); 27 | Bind().To(); 28 | Bind().To(); 29 | 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/EfCarImageDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess.EntityFramework; 2 | using DataAccess.Abstract; 3 | using Entities.Concrete; 4 | using Entities.DTOs; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Linq; 9 | 10 | namespace DataAccess.Concrete.EntityFramework 11 | { 12 | public class EfCarImageDal : EfEntityRepositoryBase, ICarImageDal 13 | { 14 | public List GetCarImageDetails() 15 | { 16 | using (RentACarContext context = new RentACarContext()) 17 | { 18 | var result = from cr in context.CarImages 19 | join c in context.Cars on cr.CarId equals c.Id 20 | join b in context.Brands on c.BrandId equals b.Id 21 | join c2 in context.Colors on c.ColorId equals c2.Id 22 | select new CarImageDto { Id = cr.Id, BrandName = b.BrandName, ColorName = c2.ColorName, ModelYear = c.ModelYear, DailyPrice = c.DailyPrice, Description = c.Description, ImagePath = cr.ImagePath, Date = cr.Date }; 23 | return result.ToList(); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Core/Aspects/Autofac/Performance/PerformanceAspect.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using Core.Utilities.Interceptors; 3 | using Core.Utilities.IoC; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Text; 8 | using Microsoft.Extensions.DependencyInjection; 9 | 10 | namespace Core.Aspects.Autofac.Performance 11 | { 12 | public class PerformanceAspect : MethodInterception 13 | { 14 | private int _interval; 15 | private Stopwatch _stopwatch; 16 | 17 | public PerformanceAspect(int interval) 18 | { 19 | _interval = interval; 20 | _stopwatch = ServiceTool.ServiceProvider.GetService(); 21 | } 22 | 23 | 24 | protected override void OnBefore(IInvocation invocation) 25 | { 26 | _stopwatch.Start(); 27 | } 28 | 29 | protected override void OnAfter(IInvocation invocation) 30 | { 31 | if (_stopwatch.Elapsed.TotalSeconds > _interval) 32 | { 33 | Debug.WriteLine($"Performance : {invocation.Method.DeclaringType.FullName}.{invocation.Method.Name}-->{_stopwatch.Elapsed.TotalSeconds}"); 34 | } 35 | _stopwatch.Reset(); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Business/Constants/Messages.cs: -------------------------------------------------------------------------------- 1 | using Entities.Concrete; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Runtime.Serialization; 5 | using System.Text; 6 | 7 | namespace Business.Constants 8 | { 9 | public static class Messages 10 | { 11 | public static string Added = "Ekleme işlemi başarılı"; 12 | public static string NameInvalid = "Eksik veya hatalı bilgi"; 13 | public static string Updated = "Güncelleme işlemi başarılı"; 14 | public static string Deleted = "Silme işlemi başarılı"; 15 | public static string DeletedInvalid = "Silme işlemi başarısız"; 16 | public static string Listed = "Listeleme işlemi başarılı"; 17 | public static string CarImageLimitExceeded = "Bir arabanın 5'den fazla resmi olamaz."; 18 | public static string AuthorizationDenied = "Yetkiniz yok."; 19 | public static string UserRegistered = "Kayıt oldu."; 20 | public static string UserNotFound = "Kullanıcı bulunamadı."; 21 | public static string PasswordError = "Parola hatası."; 22 | public static string SuccessfulLogin = "Başarılı giriş."; 23 | public static string UserAlreadyExists = "Kullanıcı mevcut."; 24 | public static string AccessTokenCreated="Token oluşturuldu"; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Business/BusinessAspects/Autofac/SecuredOperation.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Interceptors; 2 | using Core.Utilities.IoC; 3 | using Microsoft.AspNetCore.Http; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using Castle.DynamicProxy; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Core.Extensions; 10 | using Business.Constants; 11 | 12 | namespace Business.BusinessAspects.Autofac 13 | { 14 | //JWT 15 | public class SecuredOperation : MethodInterception 16 | { 17 | private string[] _roles; 18 | private IHttpContextAccessor _httpContextAccessor; 19 | 20 | public SecuredOperation(string roles) 21 | { 22 | _roles = roles.Split(','); 23 | _httpContextAccessor = ServiceTool.ServiceProvider.GetService(); 24 | 25 | } 26 | 27 | protected override void OnBefore(IInvocation invocation) 28 | { 29 | var roleClaims = _httpContextAccessor.HttpContext.User.ClaimRoles(); 30 | foreach (var role in _roles) 31 | { 32 | if (roleClaims.Contains(role)) 33 | { 34 | return; 35 | } 36 | } 37 | throw new Exception(Messages.AuthorizationDenied); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /WebAPI/Controllers/WeatherForecastController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace WebAPI.Controllers 9 | { 10 | [ApiController] 11 | [Route("[controller]")] 12 | public class WeatherForecastController : ControllerBase 13 | { 14 | private static readonly string[] Summaries = new[] 15 | { 16 | "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" 17 | }; 18 | 19 | private readonly ILogger _logger; 20 | 21 | public WeatherForecastController(ILogger logger) 22 | { 23 | _logger = logger; 24 | } 25 | 26 | [HttpGet] 27 | public IEnumerable Get() 28 | { 29 | var rng = new Random(); 30 | return Enumerable.Range(1, 5).Select(index => new WeatherForecast 31 | { 32 | Date = DateTime.Now.AddDays(index), 33 | TemperatureC = rng.Next(-20, 55), 34 | Summary = Summaries[rng.Next(Summaries.Length)] 35 | }) 36 | .ToArray(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Core/Aspects/Autofac/Caching/CacheAspect.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using Core.CrossCuttingConcerns.Caching; 3 | using Core.Utilities.Interceptors; 4 | using Core.Utilities.IoC; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | using Microsoft.Extensions.DependencyInjection; 10 | 11 | namespace Core.Aspects.Autofac.Caching 12 | { 13 | public class CacheAspect : MethodInterception 14 | { 15 | private int _duration; 16 | private ICacheManager _cacheManager; 17 | 18 | public CacheAspect(int duration = 60) 19 | { 20 | _duration = duration; 21 | _cacheManager = ServiceTool.ServiceProvider.GetService(); 22 | } 23 | 24 | public override void Intercept(IInvocation invocation) 25 | { 26 | var methodName = string.Format($"{invocation.Method.ReflectedType.FullName}.{invocation.Method.Name}"); 27 | var arguments = invocation.Arguments.ToList(); 28 | var key = $"{methodName}({string.Join(",", arguments.Select(x => x?.ToString() ?? ""))})"; 29 | if (_cacheManager.IsAdd(key)) 30 | { 31 | invocation.ReturnValue = _cacheManager.Get(key); 32 | return; 33 | } 34 | invocation.Proceed(); 35 | _cacheManager.Add(key, invocation.ReturnValue, _duration); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/EfRentalDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess.EntityFramework; 2 | using DataAccess.Abstract; 3 | using Entities.Concrete; 4 | using Entities.DTOs; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Linq; 9 | 10 | namespace DataAccess.Concrete.EntityFramework 11 | { 12 | public class EfRentalDal : EfEntityRepositoryBase, IRentalDal 13 | { 14 | 15 | public List GetRentalDetails() 16 | { 17 | using (RentACarContext context = new RentACarContext()) 18 | { 19 | 20 | var result = from r in context.Rentals 21 | join c in context.Cars on r.CarId equals c.Id 22 | join b in context.Brands on c.BrandId equals b.Id 23 | join c2 in context.Colors on c.ColorId equals c2.Id 24 | join c3 in context.Customers on r.CustomerId equals c3.Id 25 | join u in context.Users on c3.UserId equals u.Id 26 | select new RentalDto { Id = r.Id, BrandName = b.BrandName, ColorName = c2.ColorName, ModelYear = c.ModelYear, DailyPrice = c.DailyPrice, Description = c.Description, FirstName = u.FirstName, LastName = u.LastName, RentDate = r.RentDate, ReturnDate = r.ReturnDate,CompanyName=c3.CompanyName }; 27 | return result.ToList(); 28 | 29 | 30 | 31 | 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Core/Utilities/Security/Hashing/HashingHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | 6 | namespace Core.Utilities.Security.Hashing 7 | { 8 | //Hashleme ve tuzlama aracı. 9 | //Hashleme yapacağımız zaman kullanacağımız araç. 10 | public class HashingHelper 11 | { 12 | //Verilen Passwordun Hashini ve saltını oluşturacak. 13 | public static void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt) 14 | { 15 | using (var hmac = new System.Security.Cryptography.HMACSHA512()) 16 | { 17 | passwordSalt = hmac.Key; 18 | passwordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password)); 19 | } 20 | } 21 | //Password Hashini doğruluyoruz. 22 | //Out vermememizin sebebi o değerleri biz veriyoruz. 23 | public static bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt) 24 | { 25 | using (var hmac = new System.Security.Cryptography.HMACSHA512(passwordSalt)) 26 | { 27 | var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password)); 28 | for (int i = 0; i < computedHash.Length; i++) 29 | { 30 | if (computedHash[i] != passwordHash[i]) 31 | { 32 | return false; 33 | } 34 | } 35 | } 36 | 37 | 38 | return true; 39 | } 40 | 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Core/Aspects/Autofac/Validation/ValidationAspect.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using Core.CrossCuttingConcerns.Validation; 3 | using Core.Utilities.Interceptors; 4 | using FluentValidation; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Text; 9 | 10 | namespace Core.Aspects.Autofac.Validation 11 | { 12 | public class ValidationAspect : MethodInterception 13 | { 14 | //Burada Dependency Injection yapıyoruz. 15 | //Parametreden gelen Type Doğrulama type'i değilse ekrana hata mesajı fırlatıyoruz. 16 | private Type _validatorType; 17 | public ValidationAspect(Type validatorType) 18 | { 19 | if (!typeof(IValidator).IsAssignableFrom(validatorType)) 20 | { 21 | throw new System.Exception("Bu bir doğrulama sınıfı değil"); 22 | } 23 | _validatorType = validatorType; 24 | } 25 | //Burada ise Kod Ezme işlemi gerçekleşiyor ve içini istediğimiz gibi kodluyoruz 26 | //Attribute'leri Methoddan önce çalıştırmak istediğimizi burada kodluyoruz. 27 | protected override void OnBefore(IInvocation invocation) 28 | { 29 | var validator = (IValidator)Activator.CreateInstance(_validatorType); 30 | var entityType = _validatorType.BaseType.GetGenericArguments()[0]; 31 | var entities = invocation.Arguments.Where(t => t.GetType() == entityType); 32 | foreach (var entity in entities) 33 | { 34 | ValidationTool.Validate(validator, entity); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Business/Concrete/ColorManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.BusinessAspects.Autofac; 3 | using Business.Constants; 4 | using Business.ValidationRules.FluentValidation; 5 | using Core.Aspects.Autofac.Caching; 6 | using Core.Aspects.Autofac.Validation; 7 | using Core.Utilities.Results; 8 | using DataAccess.Abstract; 9 | using Entities.Concrete; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Text; 13 | 14 | namespace Business.Concrete 15 | { 16 | public class ColorManager : IColorService 17 | { 18 | IColorDal _colorsDal; 19 | public ColorManager(IColorDal colorsDal) 20 | { 21 | _colorsDal = colorsDal; 22 | } 23 | [SecuredOperation("brand.add")] 24 | [ValidationAspect(typeof(ColorValidator))] 25 | public IResult Add(Color color) 26 | { 27 | _colorsDal.Add(color); 28 | return new SuccessResult(Messages.Added); 29 | 30 | } 31 | 32 | public IResult Delete(Color color) 33 | { 34 | _colorsDal.Delete(color); 35 | return new SuccessResult(Messages.Deleted); 36 | } 37 | 38 | public IDataResult> GetAll() 39 | { 40 | return new SuccessDataResult>(_colorsDal.GetAll()); 41 | } 42 | [CacheAspect] 43 | public IDataResult GetById(int colorId) 44 | { 45 | return new SuccessDataResult(_colorsDal.Get(p => p.Id == colorId)); 46 | } 47 | [ValidationAspect(typeof(ColorValidator))] 48 | public IResult Update(Color color) 49 | { 50 | _colorsDal.Update(color); 51 | return new SuccessResult(Messages.Added); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Business/Concrete/CustomerManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.BusinessAspects.Autofac; 3 | using Business.Constants; 4 | using Business.ValidationRules.FluentValidation; 5 | using Core.Aspects.Autofac.Validation; 6 | using Core.Utilities.Results; 7 | using DataAccess.Abstract; 8 | using Entities.Concrete; 9 | using Entities.DTOs; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Text; 13 | 14 | namespace Business.Concrete 15 | { 16 | public class CustomerManager : ICustomerService 17 | { 18 | ICustomerDal _customerDal; 19 | public CustomerManager(ICustomerDal customerDal) 20 | { 21 | _customerDal = customerDal; 22 | } 23 | [SecuredOperation("brand.add")] 24 | [ValidationAspect(typeof(CustomerValidator))] 25 | public IResult Add(Customer customer) 26 | { 27 | _customerDal.Add(customer); 28 | return new SuccessResult(Messages.Added); 29 | 30 | } 31 | 32 | public IResult Delete(Customer customer) 33 | { 34 | _customerDal.Delete(customer); 35 | return new SuccessResult(Messages.Deleted); 36 | 37 | } 38 | 39 | public IDataResult> GetAll() 40 | { 41 | return new SuccessDataResult>(_customerDal.GetAll()); 42 | } 43 | 44 | public IDataResult> GetCustomerDetails() 45 | { 46 | return new SuccessDataResult>(_customerDal.GetCustomerDetails()); 47 | } 48 | [ValidationAspect(typeof(CustomerValidator))] 49 | public IResult Update(Customer customer) 50 | { 51 | _customerDal.Update(customer); 52 | return new SuccessResult(Messages.Updated); 53 | 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Business/Concrete/UserManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.BusinessAspects.Autofac; 3 | using Business.Constants; 4 | using Business.ValidationRules.FluentValidation; 5 | using Core.Aspects.Autofac.Caching; 6 | using Core.Aspects.Autofac.Validation; 7 | using Core.Utilities.Results; 8 | using DataAccess.Abstract; 9 | using Entities.Concrete; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Text; 13 | 14 | namespace Business.Concrete 15 | { 16 | public class UserManager : IUserService 17 | { 18 | IUserDal _userDal; 19 | public UserManager(IUserDal userDal) 20 | { 21 | _userDal = userDal; 22 | } 23 | [SecuredOperation("brand.add")] 24 | [ValidationAspect(typeof(UserValidator))] 25 | public IResult Add(User user) 26 | { 27 | _userDal.Add(user); 28 | return new SuccessResult(Messages.Added); 29 | } 30 | 31 | public IResult Delete(User user) 32 | { 33 | _userDal.Delete(user); 34 | return new ErrorResult(Messages.Deleted); 35 | } 36 | [CacheAspect] 37 | public IDataResult> GetAll() 38 | { 39 | return new SuccessDataResult>(_userDal.GetAll()); 40 | } 41 | [ValidationAspect(typeof(UserValidator))] 42 | public IResult Update(User user) 43 | { 44 | _userDal.Update(user); 45 | return new SuccessResult(Messages.Updated); 46 | 47 | } 48 | 49 | IDataResult> GetClaims(User user) 50 | { 51 | return new SuccessDataResult>(_userDal.GetClaims(user)); 52 | } 53 | 54 | IDataResult GetByMail(string email) 55 | { 56 | return new SuccessDataResult(_userDal.Get(u => u.Email == email)); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Core/Utilities/Interceptors/MethodInterception.cs: -------------------------------------------------------------------------------- 1 | using Castle.DynamicProxy; 2 | using System; 3 | 4 | namespace Core.Utilities.Interceptors 5 | { 6 | //Asıl olayın meydana geldiği yer tam burası. 7 | //Burası bizim methodlarımızın ana çatısı diyebileceğimiz kısım. 8 | //Attributelerin nerede çalıştıralacağını gösterdiğimiz ana çatı. 9 | //Aşağıda da görüldüğü gibi 4 virtual fonksiyonumuzun içi boş. 10 | //Bunun sebebi ise bu sınıfdan kalıtım alan ValidationAspect sınıfımızda kod ezme işlemi yapmak. 11 | //Kod ezme işlemi yapdığımızda (Virtual-Override) yapıldığında methodun içini istediğimiz gibi doldurabiliriz. 12 | public abstract class MethodInterception : MethodInterceptionBaseAttribute 13 | { 14 | protected virtual void OnBefore(IInvocation invocation) { } 15 | protected virtual void OnAfter(IInvocation invocation) { } 16 | protected virtual void OnException(IInvocation invocation, System.Exception e) { } 17 | protected virtual void OnSuccess(IInvocation invocation) { } 18 | public override void Intercept(IInvocation invocation) 19 | { 20 | var isSuccess = true; 21 | OnBefore(invocation);//Methodlarımızın başında çalıştırmak istersek. 22 | try 23 | { 24 | invocation.Proceed(); 25 | } 26 | catch (Exception e) 27 | { 28 | isSuccess = false; 29 | OnException(invocation, e);//Methodlarımız hata aldığında çalıştırmak istersek. 30 | throw; 31 | } 32 | finally 33 | { 34 | if (isSuccess) 35 | { 36 | OnSuccess(invocation);//Methodlarımız hata alsın yada almasın çalıştırmak istersek. 37 | } 38 | } 39 | OnAfter(invocation);//Methodlarımızın sonunda çalıştırmak istersek. 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /WebAPI/Controllers/AuthController.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Entities.DTOs; 3 | using Microsoft.AspNetCore.Http; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebAPI.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class AuthController : Controller 15 | { 16 | private IAuthService _authService; 17 | 18 | public AuthController(IAuthService authService) 19 | { 20 | _authService = authService; 21 | } 22 | 23 | [HttpPost("login")] 24 | public ActionResult Login(UserForLoginDto userForLoginDto) 25 | { 26 | var userToLogin = _authService.Login(userForLoginDto); 27 | if (!userToLogin.Success) 28 | { 29 | return BadRequest(userToLogin.Message); 30 | } 31 | 32 | var result = _authService.CreateAccessToken(userToLogin.Data); 33 | if (result.Success) 34 | { 35 | return Ok(result.Data); 36 | } 37 | 38 | return BadRequest(result.Message); 39 | } 40 | 41 | [HttpPost("register")] 42 | public ActionResult Register(UserForRegisterDto userForRegisterDto) 43 | { 44 | var userExists = _authService.UserExists(userForRegisterDto.Email); 45 | if (!userExists.Success) 46 | { 47 | return BadRequest(userExists.Message); 48 | } 49 | 50 | var registerResult = _authService.Register(userForRegisterDto, userForRegisterDto.Password); 51 | var result = _authService.CreateAccessToken(registerResult.Data); 52 | if (result.Success) 53 | { 54 | return Ok(result.Data); 55 | } 56 | 57 | return BadRequest(result.Message); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /DataAccess/Concrete/InMemory/InMemoryColorDal.cs: -------------------------------------------------------------------------------- 1 | using DataAccess.Abstract; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | 9 | namespace DataAccess.Concrete.InMemory 10 | { 11 | public class InMemoryColorDal:IColorDal 12 | { 13 | List _colors; 14 | public InMemoryColorDal() 15 | { 16 | _colors = new List 17 | { 18 | new Color{Id=1,ColorName="Beyaz"}, 19 | new Color{Id=2,ColorName="Kırmızı"}, 20 | new Color{Id=3,ColorName="Mavi"}, 21 | new Color{Id=4,ColorName="Siyah"}, 22 | new Color{Id=5,ColorName="Lacivert"}, 23 | 24 | }; 25 | } 26 | 27 | public void Add(Color entity) 28 | { 29 | throw new NotImplementedException(); 30 | } 31 | 32 | public void Delete(Color entity) 33 | { 34 | throw new NotImplementedException(); 35 | } 36 | 37 | public Color Get(Expression> filter) 38 | { 39 | throw new NotImplementedException(); 40 | } 41 | 42 | public void GetAll() 43 | { 44 | int sira = 0; 45 | var result = (from c in _colors 46 | orderby c.ColorName ascending 47 | select c); 48 | foreach (var color in result) 49 | { 50 | sira++; 51 | Console.WriteLine(sira + "-)" + color.ColorName); 52 | 53 | } 54 | } 55 | 56 | public List GetAll(Expression> filter = null) 57 | { 58 | throw new NotImplementedException(); 59 | } 60 | 61 | public void Update(Color entity) 62 | { 63 | throw new NotImplementedException(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /DataAccess/Concrete/InMemory/InMemoryBrandDal.cs: -------------------------------------------------------------------------------- 1 | using DataAccess.Abstract; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Linq; 7 | using System.Linq.Expressions; 8 | 9 | namespace DataAccess.Concrete.InMemory 10 | { 11 | public class InMemoryBrandDal : IBrandDal 12 | { 13 | List _brands; 14 | public InMemoryBrandDal() 15 | { 16 | 17 | 18 | _brands = new List() 19 | { 20 | new Brand { Id = 1, BrandName = "Toyota" }, 21 | new Brand { Id = 2, BrandName = "Opel" }, 22 | new Brand { Id = 3, BrandName = "BMW" }, 23 | new Brand { Id = 4, BrandName = "Scoda" }, 24 | new Brand { Id = 5, BrandName = "Fiat" }, 25 | }; 26 | 27 | 28 | } 29 | 30 | public void Add(Brand entity) 31 | { 32 | throw new NotImplementedException(); 33 | } 34 | 35 | public void Delete(Brand entity) 36 | { 37 | throw new NotImplementedException(); 38 | } 39 | 40 | public Brand Get(Expression> filter) 41 | { 42 | throw new NotImplementedException(); 43 | } 44 | 45 | public void GetAll() 46 | { 47 | int sira = 0; 48 | var result = (from b in _brands 49 | orderby b.BrandName ascending 50 | select b); 51 | foreach (var brand in result) 52 | { 53 | sira++; 54 | Console.WriteLine(sira + "-)" + brand.BrandName); 55 | } 56 | 57 | } 58 | 59 | public List GetAll(Expression> filter = null) 60 | { 61 | throw new NotImplementedException(); 62 | } 63 | 64 | public void Update(Brand entity) 65 | { 66 | throw new NotImplementedException(); 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /WebAPI/Controllers/UsersController.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Entities.Concrete; 3 | using Microsoft.AspNetCore.Http; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebAPI.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class UsersController : ControllerBase 15 | { 16 | IUserService _userService; 17 | public UsersController(IUserService userService) 18 | { 19 | _userService = userService; 20 | } 21 | [HttpPost("add")] 22 | public IActionResult Add(User user) 23 | { 24 | var result = _userService.Add(user); 25 | if(result.Success) 26 | { 27 | return Ok(result); 28 | } 29 | else 30 | { 31 | return BadRequest(result); 32 | } 33 | } 34 | [HttpDelete("delete")] 35 | public IActionResult Delete(User user) 36 | { 37 | var result = _userService.Delete(user); 38 | if(result.Success) 39 | { 40 | return Ok(result); 41 | } 42 | else 43 | { 44 | return BadRequest(result); 45 | } 46 | } 47 | [HttpPut("update")] 48 | public IActionResult Update(User user) 49 | { 50 | var result = _userService.Update(user); 51 | if(result.Success) 52 | { 53 | return Ok(result); 54 | } 55 | else 56 | { 57 | return BadRequest(result); 58 | } 59 | } 60 | [HttpGet("getall")] 61 | public IActionResult GetAll() 62 | { 63 | var result = _userService.GetAll(); 64 | if(result.Success) 65 | { 66 | return Ok(result); 67 | } 68 | else 69 | { 70 | return BadRequest(result); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Business/Concrete/BrandManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.BusinessAspects.Autofac; 3 | using Business.Constants; 4 | using Business.ValidationRules.FluentValidation; 5 | using Core.Aspects.Autofac.Caching; 6 | using Core.Aspects.Autofac.Performance; 7 | using Core.Aspects.Autofac.Transaction; 8 | using Core.Aspects.Autofac.Validation; 9 | using Core.Utilities.Results; 10 | using DataAccess.Abstract; 11 | using Entities.Concrete; 12 | using System; 13 | using System.Collections.Generic; 14 | using System.Text; 15 | using System.Threading; 16 | 17 | namespace Business.Concrete 18 | { 19 | public class BrandManager : IBrandService 20 | { 21 | IBrandDal _brandDal; 22 | public BrandManager(IBrandDal brandDal) 23 | { 24 | _brandDal = brandDal; 25 | } 26 | [SecuredOperation("brand.add")] 27 | [ValidationAspect(typeof(BrandValidator))] 28 | [CacheRemoveAspect("IBrandService.Get")] 29 | public IResult Add(Brand brand) 30 | { 31 | 32 | _brandDal.Add(brand); 33 | return new SuccessResult(Messages.Added); 34 | 35 | } 36 | 37 | public IResult Delete(Brand brand) 38 | { 39 | _brandDal.Delete(brand); 40 | return new SuccessResult(Messages.Deleted); 41 | } 42 | [CacheAspect]//key,value 43 | [PerformanceAspect(5)] 44 | public IDataResult> GetAll() 45 | { 46 | Thread.Sleep(5000); 47 | return new SuccessDataResult>(_brandDal.GetAll()); 48 | 49 | } 50 | 51 | [CacheAspect] 52 | public IDataResult GetById(int brandId) 53 | { 54 | return new SuccessDataResult(_brandDal.Get(p => p.Id == brandId)); 55 | } 56 | 57 | [ValidationAspect(typeof(BrandValidator))] 58 | [CacheRemoveAspect("IBrandService.Get")] 59 | public IResult Update(Brand brand) 60 | { 61 | 62 | _brandDal.Update(brand); 63 | return new SuccessResult(Messages.Updated); 64 | 65 | } 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Core/Utilities/Helpers/FileHelper.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.Results; 2 | using Microsoft.AspNetCore.Http; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Text; 7 | 8 | namespace Core.Utilities.Helpers 9 | { 10 | public class FileHelper 11 | { 12 | public static string Add(IFormFile file) 13 | { 14 | var sourcepath = Path.GetTempFileName(); 15 | if (file.Length > 0) 16 | { 17 | using (var stream = new FileStream(sourcepath, FileMode.Create)) 18 | { 19 | file.CopyTo(stream); 20 | } 21 | } 22 | var result = newPath(file); 23 | File.Move(sourcepath, result); 24 | return result; 25 | } 26 | public static IResult Delete(string path) 27 | { 28 | try 29 | { 30 | File.Delete(path); 31 | } 32 | catch (Exception exception) 33 | { 34 | return new ErrorResult(exception.Message); 35 | } 36 | 37 | return new SuccessResult(); 38 | } 39 | public static string Update(string sourcePath, IFormFile file) 40 | { 41 | var result = newPath(file); 42 | if (sourcePath.Length > 0) 43 | { 44 | using (var stream = new FileStream(result, FileMode.Create)) 45 | { 46 | file.CopyTo(stream); 47 | } 48 | } 49 | File.Delete(sourcePath); 50 | return result; 51 | } 52 | public static string newPath(IFormFile file) 53 | { 54 | FileInfo ff = new FileInfo(file.FileName); 55 | string fileExtension = ff.Extension; 56 | 57 | string path = Environment.CurrentDirectory + @"\Images"; 58 | var newPath = Guid.NewGuid().ToString() + "_" + DateTime.Now.Month + "_" + DateTime.Now.Day + "_" + DateTime.Now.Year + fileExtension; 59 | 60 | string result = $@"{path}\{newPath}"; 61 | return result; 62 | } 63 | 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Core/DataAccess/EntityFramework/EfEntityRepositoryBase.cs: -------------------------------------------------------------------------------- 1 | using Core.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | using System.Text; 8 | 9 | namespace Core.DataAccess.EntityFramework 10 | { 11 | public class EfEntityRepositoryBase:IEntityRepository 12 | where TEntity : class, IEntity, new() 13 | where TContext : DbContext, new() 14 | 15 | { 16 | public void Add(TEntity entity) 17 | { 18 | using (TContext context = new TContext()) 19 | { 20 | var addedEntity = context.Entry(entity); 21 | addedEntity.State = EntityState.Added; 22 | context.SaveChanges(); 23 | } 24 | } 25 | 26 | public void Delete(TEntity entity) 27 | { 28 | using (TContext context = new TContext()) 29 | { 30 | var deletedEntity = context.Entry(entity); 31 | deletedEntity.State = EntityState.Deleted; 32 | context.SaveChanges(); 33 | } 34 | } 35 | 36 | public TEntity Get(Expression> filter) 37 | { 38 | using (TContext context = new TContext()) 39 | { 40 | return context.Set().SingleOrDefault(filter); 41 | } 42 | } 43 | 44 | public List GetAll(Expression> filter = null) 45 | { 46 | using (TContext context = new TContext()) 47 | { 48 | return filter == null 49 | ? context.Set().ToList() 50 | : context.Set().Where(filter).ToList(); 51 | } 52 | } 53 | 54 | public void Update(TEntity entity) 55 | { 56 | using (TContext context = new TContext()) 57 | { 58 | var updatedEntity = context.Entry(entity); 59 | updatedEntity.State = EntityState.Modified; 60 | context.SaveChanges(); 61 | } 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Business/Concrete/RentalManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.BusinessAspects.Autofac; 3 | using Business.Constants; 4 | using Business.ValidationRules.FluentValidation; 5 | using Core.Aspects.Autofac.Validation; 6 | using Core.Utilities.Results; 7 | using DataAccess.Abstract; 8 | using Entities.Concrete; 9 | using Entities.DTOs; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Text; 13 | 14 | namespace Business.Concrete 15 | { 16 | public class RentalManager : IRentalService 17 | { 18 | IRentalDal _rentalDal; 19 | public RentalManager(IRentalDal rentalDal) 20 | { 21 | _rentalDal = rentalDal; 22 | } 23 | [SecuredOperation("brand.add")] 24 | [ValidationAspect(typeof(RentalValidator))] 25 | public IResult Add(Rental rental) 26 | { 27 | _rentalDal.Add(rental); 28 | return new SuccessResult(Messages.Added); 29 | 30 | } 31 | 32 | 33 | 34 | public IResult Delete(Rental rental) 35 | { 36 | _rentalDal.Delete(rental); 37 | return new SuccessResult(Messages.Deleted); 38 | } 39 | 40 | public IDataResult> GetAll() 41 | { 42 | return new SuccessDataResult>(_rentalDal.GetAll()); 43 | } 44 | 45 | public IDataResult GetById(int carId) 46 | { 47 | var result = _rentalDal.Get(p => p.CarId == carId); 48 | if (result != null) 49 | { 50 | return new SuccessDataResult(_rentalDal.Get(p => p.CarId == carId)); 51 | } 52 | else 53 | { 54 | return new ErrorDataResult(_rentalDal.Get(p => p.CarId == carId)); 55 | } 56 | 57 | } 58 | 59 | public IDataResult> GetRentalDetails() 60 | { 61 | return new SuccessDataResult>(_rentalDal.GetRentalDetails()); 62 | } 63 | [ValidationAspect(typeof(RentalValidator))] 64 | public IResult Update(Rental rental) 65 | { 66 | _rentalDal.Update(rental); 67 | return new SuccessResult(Messages.Updated); 68 | 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Business/DependencyResolvers/Autofac/AutofacBusinessModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Autofac.Extras.DynamicProxy; 3 | using Business.Abstract; 4 | using Business.Concrete; 5 | using Castle.DynamicProxy; 6 | using Core.Utilities.Interceptors; 7 | using Core.Utilities.Security.JWT; 8 | using DataAccess.Abstract; 9 | using DataAccess.Concrete.EntityFramework; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Text; 13 | 14 | namespace Business.DependencyResolvers.Autofac 15 | { 16 | public class AutofacBusinessModule : Module 17 | { 18 | protected override void Load(ContainerBuilder builder) 19 | { 20 | builder.RegisterType().As().SingleInstance(); 21 | builder.RegisterType().As().SingleInstance(); 22 | 23 | builder.RegisterType().As().SingleInstance(); 24 | builder.RegisterType().As().SingleInstance(); 25 | 26 | builder.RegisterType().As().SingleInstance(); 27 | builder.RegisterType().As().SingleInstance(); 28 | 29 | builder.RegisterType().As().SingleInstance(); 30 | builder.RegisterType().As().SingleInstance(); 31 | 32 | builder.RegisterType().As().SingleInstance(); 33 | builder.RegisterType().As().SingleInstance(); 34 | 35 | builder.RegisterType().As().SingleInstance(); 36 | builder.RegisterType().As().SingleInstance(); 37 | 38 | builder.RegisterType().As().SingleInstance(); 39 | builder.RegisterType().As().SingleInstance(); 40 | 41 | builder.RegisterType().As(); 42 | builder.RegisterType().As(); 43 | 44 | var assembly = System.Reflection.Assembly.GetExecutingAssembly(); 45 | 46 | builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces() 47 | .EnableInterfaceInterceptors(new ProxyGenerationOptions() 48 | { 49 | Selector = new AspectInterceptorSelector() 50 | }).SingleInstance(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /WebAPI/Controllers/ColorsController.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Entities.Concrete; 3 | using Microsoft.AspNetCore.Http; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebAPI.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class ColorsController : ControllerBase 15 | { 16 | IColorService _colorService; 17 | public ColorsController(IColorService colorService) 18 | { 19 | _colorService = colorService; 20 | } 21 | [HttpPost("add")] 22 | public IActionResult Add(Color color) 23 | { 24 | var result = _colorService.Add(color); 25 | if (result.Success) 26 | { 27 | return Ok(result); 28 | } 29 | else 30 | { 31 | return BadRequest(result); 32 | } 33 | } 34 | [HttpDelete("delete")] 35 | public IActionResult Delete(Color color) 36 | { 37 | var result = _colorService.Delete(color); 38 | if (result.Success) 39 | { 40 | return Ok(result); 41 | } 42 | else 43 | { 44 | return BadRequest(result); 45 | } 46 | } 47 | [HttpPut("update")] 48 | public IActionResult Update(Color color) 49 | { 50 | var result = _colorService.Update(color); 51 | if (result.Success) 52 | { 53 | return Ok(result); 54 | } 55 | else 56 | { 57 | return BadRequest(result); 58 | } 59 | } 60 | [HttpGet("getall")] 61 | public IActionResult GetAll() 62 | { 63 | var result = _colorService.GetAll(); 64 | if (result.Success) 65 | { 66 | return Ok(result); 67 | } 68 | else 69 | { 70 | return BadRequest(result); 71 | } 72 | } 73 | [HttpGet("getbyid")] 74 | public IActionResult GetById(int colorId) 75 | { 76 | var result = _colorService.GetById(colorId); 77 | if (result.Success) 78 | { 79 | return Ok(result); 80 | } 81 | else 82 | { 83 | return BadRequest(result); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /WebAPI/Controllers/RentalsController.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Entities.Concrete; 3 | using Microsoft.AspNetCore.Http; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebAPI.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class RentalsController : ControllerBase 15 | { 16 | IRentalService _rentalService; 17 | public RentalsController(IRentalService rentalService) 18 | { 19 | _rentalService = rentalService; 20 | } 21 | [HttpPost("add")] 22 | public IActionResult Add(Rental rental) 23 | { 24 | var result = _rentalService.Add(rental); 25 | if(result.Success) 26 | { 27 | return Ok(result); 28 | } 29 | else 30 | { 31 | return BadRequest(result); 32 | } 33 | } 34 | [HttpDelete("delete")] 35 | public IActionResult Delete(Rental rental) 36 | { 37 | var result = _rentalService.Delete(rental); 38 | if(result.Success) 39 | { 40 | return Ok(result); 41 | } 42 | else 43 | { 44 | return BadRequest(result); 45 | } 46 | } 47 | [HttpPut("update")] 48 | public IActionResult Update(Rental rental) 49 | { 50 | var result = _rentalService.Update(rental); 51 | if(result.Success) 52 | { 53 | return Ok(result); 54 | } 55 | else 56 | { 57 | return BadRequest(result); 58 | } 59 | } 60 | [HttpGet("getall")] 61 | public IActionResult GetAll() 62 | { 63 | var result = _rentalService.GetRentalDetails(); 64 | if(result.Success) 65 | { 66 | return Ok(result); 67 | } 68 | else 69 | { 70 | return BadRequest(result); 71 | } 72 | } 73 | [HttpGet("getrentaldetails")] 74 | public IActionResult GetRentalDetails() 75 | { 76 | var result = _rentalService.GetRentalDetails(); 77 | if(result.Success) 78 | { 79 | return Ok(result); 80 | } 81 | else 82 | { 83 | return BadRequest(result); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /DataAccess/Concrete/EntityFramework/EfCarDal.cs: -------------------------------------------------------------------------------- 1 | using Core.DataAccess.EntityFramework; 2 | using DataAccess.Abstract; 3 | using Entities.Concrete; 4 | using Microsoft.EntityFrameworkCore; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Linq.Expressions; 9 | using System.Text; 10 | 11 | namespace DataAccess.Concrete.EntityFramework 12 | { 13 | public class EfCarDal : EfEntityRepositoryBase, ICarDal 14 | { 15 | public List GetCarAsc() 16 | { 17 | using (RentACarContext context = new RentACarContext()) 18 | { 19 | var result = from c in context.Cars 20 | join b in context.Brands on c.BrandId equals b.Id 21 | join c2 in context.Colors on c.ColorId equals c2.Id 22 | orderby c.DailyPrice ascending 23 | select new CarDto { Id = c.Id, BrandName = b.BrandName, ColorName = c2.ColorName, ModelYear = c.ModelYear, DailyPrice = c.DailyPrice, Description = c.Description }; 24 | return result.ToList(); 25 | } 26 | 27 | } 28 | 29 | public List GetCarDesc() 30 | { 31 | 32 | using (RentACarContext context = new RentACarContext()) 33 | { 34 | var result = from c in context.Cars 35 | join b in context.Brands on c.BrandId equals b.Id 36 | join c2 in context.Colors on c.ColorId equals c2.Id 37 | orderby c.DailyPrice descending 38 | select new CarDto { Id = c.Id, BrandName = b.BrandName, ColorName = c2.ColorName, ModelYear = c.ModelYear, DailyPrice = c.DailyPrice, Description = c.Description }; 39 | return result.ToList(); 40 | } 41 | } 42 | 43 | public List GetCarDetails() 44 | { 45 | using (RentACarContext context=new RentACarContext()) 46 | { 47 | var result = from c in context.Cars 48 | join b in context.Brands on c.BrandId equals b.Id 49 | join c2 in context.Colors on c.ColorId equals c2.Id 50 | select new CarDto { Id = c.Id, BrandName = b.BrandName, ColorName = c2.ColorName, ModelYear = c.ModelYear, DailyPrice = c.DailyPrice, Description = c.Description }; 51 | return result.ToList(); 52 | 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /WebAPI/Controllers/BrandsController.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Entities.Concrete; 3 | using Microsoft.AspNetCore.Http; 4 | using Microsoft.AspNetCore.Mvc; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebAPI.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class BrandsController : ControllerBase 15 | { 16 | 17 | IBrandService _brandService; 18 | public BrandsController(IBrandService brandService) 19 | { 20 | _brandService = brandService; 21 | } 22 | [HttpGet("getall")]//Diğer HttpGet'lerden ayırmak için isimlendiriyoruz. 23 | public IActionResult GetAll() 24 | { 25 | var result = _brandService.GetAll(); 26 | if(result.Success) 27 | { 28 | return Ok(result); 29 | } 30 | else 31 | { 32 | return BadRequest(result); 33 | } 34 | } 35 | [HttpGet("getbyid")] 36 | public IActionResult GetById(int brandId) 37 | { 38 | var result = _brandService.GetById(brandId); 39 | if(result.Success) 40 | { 41 | return Ok(result); 42 | } 43 | else 44 | { 45 | return BadRequest(result); 46 | } 47 | } 48 | [HttpPost("add")] 49 | public IActionResult Add(Brand brand) 50 | { 51 | var result = _brandService.Add(brand); 52 | if(result.Success) 53 | { 54 | return Ok(result); 55 | } 56 | else 57 | { 58 | return BadRequest(result); 59 | } 60 | } 61 | [HttpDelete("delete")] 62 | public IActionResult Delete(Brand brand) 63 | { 64 | var result = _brandService.Delete(brand); 65 | if(result.Success) 66 | { 67 | return Ok(result); 68 | } 69 | else 70 | { 71 | return BadRequest(result); 72 | } 73 | } 74 | [HttpPut("update")] 75 | public IActionResult Update(Brand brand) 76 | { 77 | var result = _brandService.Update(brand); 78 | if(result.Success) 79 | { 80 | return Ok(result); 81 | } 82 | else 83 | { 84 | return BadRequest(result); 85 | } 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /WebAPI/Controllers/CustomersController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Business.Abstract; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | using Entities.Concrete; 9 | 10 | namespace WebAPI.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class CustomersController : ControllerBase 15 | { 16 | ICustomerService _customerService; 17 | public CustomersController(ICustomerService customerService) 18 | { 19 | _customerService = customerService; 20 | } 21 | [HttpPost("add")] 22 | public IActionResult Add(Customer customer) 23 | { 24 | var result = _customerService.Add(customer); 25 | if(result.Success) 26 | { 27 | return Ok(result); 28 | } 29 | else 30 | { 31 | return BadRequest(result); 32 | } 33 | } 34 | [HttpDelete("delete")] 35 | public IActionResult Delete(Customer customer) 36 | { 37 | var result = _customerService.Delete(customer); 38 | if(result.Success) 39 | { 40 | return Ok(result); 41 | } 42 | else 43 | { 44 | return BadRequest(result); 45 | } 46 | } 47 | [HttpPut("update")] 48 | public IActionResult Update(Customer customer) 49 | { 50 | var result = _customerService.Update(customer); 51 | if(result.Success) 52 | { 53 | return Ok(result); 54 | } 55 | else 56 | { 57 | return BadRequest(result); 58 | } 59 | } 60 | [HttpGet("getall")] 61 | public IActionResult GetAll() 62 | { 63 | var result = _customerService.GetAll(); 64 | if(result.Success) 65 | { 66 | return Ok(result); 67 | } 68 | else 69 | { 70 | return BadRequest(result); 71 | } 72 | } 73 | [HttpGet("getcustomerdetails")] 74 | public IActionResult GetCustomerDetails() 75 | { 76 | var result = _customerService.GetCustomerDetails(); 77 | if(result.Success) 78 | { 79 | return Ok(result); 80 | } 81 | else 82 | { 83 | return BadRequest(result); 84 | } 85 | 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Core/CrossCuttingConcerns/Caching/Microsoft/MemoryCacheManager.cs: -------------------------------------------------------------------------------- 1 | using Core.Utilities.IoC; 2 | using Microsoft.Extensions.Caching.Memory; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using System.Text.RegularExpressions; 8 | using System.Linq; 9 | 10 | namespace Core.CrossCuttingConcerns.Caching.Microsoft 11 | { 12 | //Adapter Pattern 13 | //Var olan sistemi kendi sistemine uyarlamak. 14 | public class MemoryCacheManager : ICacheManager 15 | { 16 | IMemoryCache _memoryCache; 17 | public MemoryCacheManager() 18 | { 19 | _memoryCache = ServiceTool.ServiceProvider.GetService(); 20 | } 21 | public void Add(string key, object value, int duration) 22 | { 23 | _memoryCache.Set(key, value, TimeSpan.FromMinutes(duration)); 24 | } 25 | 26 | public T Get(string key) 27 | { 28 | return _memoryCache.Get(key); 29 | } 30 | 31 | public object Get(string key) 32 | { 33 | return _memoryCache.Get(key); 34 | } 35 | 36 | public bool IsAdd(string key) 37 | { 38 | return _memoryCache.TryGetValue(key, out _); 39 | } 40 | 41 | public void Remove(string key) 42 | { 43 | _memoryCache.Remove(key); 44 | } 45 | //Çalışma anında bellekten silmeye yarar. 46 | //MemoryCache dökümantasyonu. 47 | public void RemoveByPattern(string pattern) 48 | { 49 | var cacheEntriesCollectionDefinition = typeof(MemoryCache).GetProperty("EntriesCollection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); 50 | var cacheEntriesCollection = cacheEntriesCollectionDefinition.GetValue(_memoryCache) as dynamic; 51 | List cacheCollectionValues = new List(); 52 | 53 | foreach (var cacheItem in cacheEntriesCollection) 54 | { 55 | ICacheEntry cacheItemValue = cacheItem.GetType().GetProperty("Value").GetValue(cacheItem, null); 56 | cacheCollectionValues.Add(cacheItemValue); 57 | } 58 | 59 | var regex = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase); 60 | var keysToRemove = cacheCollectionValues.Where(d => regex.IsMatch(d.Key.ToString())).Select(d => d.Key).ToList(); 61 | 62 | foreach (var key in keysToRemove) 63 | { 64 | _memoryCache.Remove(key); 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Business/Concrete/AuthManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Core.Utilities.Results; 3 | using Core.Utilities.Security.Hashing; 4 | using Core.Utilities.Security.JWT; 5 | using Business.Constants; 6 | using Entities.Concrete; 7 | using Entities.DTOs; 8 | using System.Collections.Generic; 9 | using System; 10 | using System.Text; 11 | 12 | 13 | 14 | namespace Business.Concrete 15 | { 16 | public class AuthManager : IAuthService 17 | { 18 | private IUserService _userService; 19 | private ITokenHelper _tokenHelper; 20 | 21 | public AuthManager(IUserService userService, ITokenHelper tokenHelper) 22 | { 23 | _userService = userService; 24 | _tokenHelper = tokenHelper; 25 | } 26 | 27 | public IDataResult Register(UserForRegisterDto userForRegisterDto, string password) 28 | { 29 | byte[] passwordHash, passwordSalt; 30 | HashingHelper.CreatePasswordHash(password, out passwordHash, out passwordSalt); 31 | var user = new User 32 | { 33 | Email = userForRegisterDto.Email, 34 | FirstName = userForRegisterDto.FirstName, 35 | LastName = userForRegisterDto.LastName, 36 | PasswordHash = passwordHash, 37 | PasswordSalt = passwordSalt, 38 | Status = true 39 | }; 40 | _userService.Add(user); 41 | return new SuccessDataResult(user, Messages.UserRegistered); 42 | } 43 | 44 | public IDataResult Login(UserForLoginDto userForLoginDto) 45 | { 46 | var userToCheck = _userService.GetByMail(userForLoginDto.Email); 47 | if (userToCheck == null) 48 | { 49 | return new ErrorDataResult(Messages.UserNotFound); 50 | } 51 | 52 | if (!HashingHelper.VerifyPasswordHash(userForLoginDto.Password, userToCheck.Data.PasswordHash, userToCheck.Data.PasswordSalt)) 53 | { 54 | return new ErrorDataResult(Messages.PasswordError); 55 | } 56 | 57 | return new SuccessDataResult(userToCheck.Data, Messages.SuccessfulLogin); 58 | } 59 | 60 | public IResult UserExists(string email) 61 | { 62 | if (_userService.GetByMail(email).Data != null) 63 | { 64 | return new ErrorResult(Messages.UserAlreadyExists); 65 | } 66 | return new SuccessResult(); 67 | } 68 | 69 | public IDataResult CreateAccessToken(User user) 70 | { 71 | var claims = _userService.GetClaims(user); 72 | var accessToken = _tokenHelper.CreateToken(user, claims.Data); 73 | return new SuccessDataResult(accessToken, Messages.AccessTokenCreated); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Core/Utilities/Security/JWT/JwtHelper.cs: -------------------------------------------------------------------------------- 1 | using Core.Extensions; 2 | using Core.Utilities.Security.Encryption; 3 | using Entities.Concrete; 4 | using Microsoft.Extensions.Configuration; 5 | using Microsoft.IdentityModel.Tokens; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.IdentityModel.Tokens.Jwt; 9 | using System.Linq; 10 | using System.Security.Claims; 11 | using System.Text; 12 | 13 | namespace Core.Utilities.Security.JWT 14 | { 15 | public class JwtHelper : ITokenHelper 16 | { 17 | public IConfiguration Configuration { get; }//Api'deki appsettings dosyasını okumaya yarıyor. 18 | private TokenOptions _tokenOptions;//Dosya içindeki bilgileri nesneye atıyoruz. 19 | private DateTime _accessTokenExpiration;//AccessToken ne zaman etkisizleşicek. 20 | public JwtHelper(IConfiguration configuration) 21 | { 22 | Configuration = configuration; 23 | //Git appsetting içindeki bölümü al o bölümde string içindeki bölüm. 24 | //Oradaki bölümdeki bilgileri tek tek ilgili tokenoptions'a map ediyor yani atıyor. 25 | _tokenOptions = Configuration.GetSection("TokenOptions").Get(); 26 | 27 | } 28 | //Kullanıcı için token oluşturuyor. 29 | //User ve claimlere göre oluşturuyor. 30 | public AccessToken CreateToken(User user, List operationClaims) 31 | { 32 | _accessTokenExpiration = DateTime.Now.AddMinutes(_tokenOptions.AccessTokenExpiration); 33 | var securityKey = SecurityKeyHelper.CreateSecurityKey(_tokenOptions.SecurityKey); 34 | var signingCredentials = SigningCredentialsHelper.CreateSigningCredentials(securityKey); 35 | var jwt = CreateJwtSecurityToken(_tokenOptions, user, signingCredentials, operationClaims); 36 | var jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); 37 | var token = jwtSecurityTokenHandler.WriteToken(jwt); 38 | 39 | return new AccessToken 40 | { 41 | Token = token, 42 | Expiration = _accessTokenExpiration 43 | }; 44 | 45 | } 46 | 47 | public JwtSecurityToken CreateJwtSecurityToken(TokenOptions tokenOptions, User user, 48 | SigningCredentials signingCredentials, List operationClaims) 49 | { 50 | var jwt = new JwtSecurityToken( 51 | issuer: tokenOptions.Issuer, 52 | audience: tokenOptions.Audience, 53 | expires: _accessTokenExpiration, 54 | notBefore: DateTime.Now, 55 | claims: SetClaims(user, operationClaims), 56 | signingCredentials: signingCredentials 57 | ); 58 | return jwt; 59 | } 60 | 61 | private IEnumerable SetClaims(User user, List operationClaims) 62 | { 63 | var claims = new List(); 64 | claims.AddNameIdentifier(user.Id.ToString()); 65 | claims.AddEmail(user.Email); 66 | claims.AddName($"{user.FirstName} {user.LastName}"); 67 | claims.AddRoles(operationClaims.Select(c => c.Name).ToArray()); 68 | 69 | return claims; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Business/Concrete/CarManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.BusinessAspects.Autofac; 3 | using Business.Constants; 4 | using Business.ValidationRules.FluentValidation; 5 | using Core.Aspects.Autofac.Caching; 6 | using Core.Aspects.Autofac.Transaction; 7 | using Core.Aspects.Autofac.Validation; 8 | using Core.Utilities.Results; 9 | using DataAccess.Abstract; 10 | using Entities.Concrete; 11 | using System; 12 | using System.Collections.Generic; 13 | using System.Linq; 14 | using System.Linq.Expressions; 15 | using System.Text; 16 | 17 | namespace Business.Concrete 18 | { 19 | public class CarManager : ICarService 20 | { 21 | ICarDal _carDal; 22 | public CarManager(ICarDal carDal) 23 | { 24 | _carDal = carDal; 25 | } 26 | 27 | 28 | public IResult Delete(Car car) 29 | { 30 | _carDal.Delete(car); 31 | return new SuccessResult(Messages.Deleted); 32 | } 33 | 34 | 35 | 36 | public IDataResult> GetCarsByBrandId(int id) 37 | { 38 | 39 | return new SuccessDataResult>(_carDal.GetAll(p => p.BrandId == id)); 40 | } 41 | 42 | public IDataResult> GetCarsByColorId(int id) 43 | { 44 | return new SuccessDataResult>(_carDal.GetAll(p => p.ColorId == id)); 45 | } 46 | [SecuredOperation("brand.add")] 47 | [ValidationAspect(typeof(CarValidator))] 48 | public IResult Update(Car car) 49 | { 50 | 51 | _carDal.Update(car); 52 | return new SuccessResult(Messages.Updated); 53 | 54 | } 55 | [CacheAspect] 56 | public IDataResult> GetAll() 57 | { 58 | return new SuccessDataResult>(_carDal.GetAll()); 59 | } 60 | [ValidationAspect(typeof(CarValidator))] 61 | public IResult Add(Car car) 62 | { 63 | _carDal.Add(car); 64 | return new SuccessResult(Messages.Added); 65 | 66 | 67 | } 68 | 69 | public IDataResult> GetByDailyPrice(decimal min, decimal max) 70 | { 71 | 72 | return new SuccessDataResult>(_carDal.GetAll(p => p.DailyPrice >= min && p.DailyPrice <= max)); 73 | } 74 | [CacheAspect] 75 | public IDataResult GetById(int carId) 76 | { 77 | return new SuccessDataResult(_carDal.Get(p => p.Id == carId)); 78 | } 79 | 80 | public IDataResult> GetCarDetails() 81 | { 82 | return new SuccessDataResult>(_carDal.GetCarDetails()); 83 | } 84 | 85 | public IDataResult> GetCarAsc() 86 | { 87 | return new SuccessDataResult>(_carDal.GetCarAsc()); 88 | } 89 | 90 | public IDataResult> GetCarDesc() 91 | { 92 | return new SuccessDataResult>(_carDal.GetCarDesc()); 93 | } 94 | [TransactionScopeAspect] 95 | public IResult AddTransactionalTest(Car car) 96 | { 97 | Add(car); 98 | if(car.DailyPrice<100) 99 | { 100 | throw new Exception(); 101 | } 102 | Add(car); 103 | return null; 104 | 105 | } 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /ReCapProject.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30907.101 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Entities", "Entities\Entities.csproj", "{07B5A941-6662-4108-BD18-C199B41F4497}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataAccess", "DataAccess\DataAccess.csproj", "{4405C450-A404-4809-AE8D-CE28B6314DF0}" 9 | EndProject 10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Business", "Business\Business.csproj", "{3BFAA9BD-E930-4E9D-9B0A-AAED04E565D9}" 11 | EndProject 12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleUI", "ConsoleUI\ConsoleUI.csproj", "{4EB1A8F8-5975-4EA0-92E2-EE82E4759CD8}" 13 | EndProject 14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Core", "Core\Core.csproj", "{EF34AA21-D5CA-4D6E-B258-15A6DF9EECA8}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAPI", "WebAPI\WebAPI.csproj", "{A187A146-5868-4C21-98DD-808D026B5E57}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {07B5A941-6662-4108-BD18-C199B41F4497}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {07B5A941-6662-4108-BD18-C199B41F4497}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {07B5A941-6662-4108-BD18-C199B41F4497}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {07B5A941-6662-4108-BD18-C199B41F4497}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {4405C450-A404-4809-AE8D-CE28B6314DF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {4405C450-A404-4809-AE8D-CE28B6314DF0}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {4405C450-A404-4809-AE8D-CE28B6314DF0}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {4405C450-A404-4809-AE8D-CE28B6314DF0}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {3BFAA9BD-E930-4E9D-9B0A-AAED04E565D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {3BFAA9BD-E930-4E9D-9B0A-AAED04E565D9}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {3BFAA9BD-E930-4E9D-9B0A-AAED04E565D9}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {3BFAA9BD-E930-4E9D-9B0A-AAED04E565D9}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {4EB1A8F8-5975-4EA0-92E2-EE82E4759CD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {4EB1A8F8-5975-4EA0-92E2-EE82E4759CD8}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {4EB1A8F8-5975-4EA0-92E2-EE82E4759CD8}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {4EB1A8F8-5975-4EA0-92E2-EE82E4759CD8}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {EF34AA21-D5CA-4D6E-B258-15A6DF9EECA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {EF34AA21-D5CA-4D6E-B258-15A6DF9EECA8}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {EF34AA21-D5CA-4D6E-B258-15A6DF9EECA8}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {EF34AA21-D5CA-4D6E-B258-15A6DF9EECA8}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {A187A146-5868-4C21-98DD-808D026B5E57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {A187A146-5868-4C21-98DD-808D026B5E57}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {A187A146-5868-4C21-98DD-808D026B5E57}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {A187A146-5868-4C21-98DD-808D026B5E57}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | GlobalSection(ExtensibilityGlobals) = postSolution 53 | SolutionGuid = {45003E27-8465-4C9D-8615-64ED3EABCC0B} 54 | EndGlobalSection 55 | EndGlobal 56 | -------------------------------------------------------------------------------- /WebAPI/Controllers/CarsImagesController.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Entities.Concrete; 3 | using Microsoft.AspNetCore.Hosting; 4 | using Microsoft.AspNetCore.Http; 5 | using Microsoft.AspNetCore.Mvc; 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Threading.Tasks; 10 | 11 | namespace WebAPI.Controllers 12 | { 13 | [Route("api/[controller]")] 14 | [ApiController] 15 | public class CarsImagesController : ControllerBase 16 | { 17 | ICarImageService _carImageService; 18 | 19 | public CarsImagesController(ICarImageService carImageService) 20 | { 21 | _carImageService = carImageService; 22 | } 23 | [HttpPost("add")] 24 | public IActionResult Add([FromForm(Name = ("Image"))] IFormFile file, [FromForm] CarImage carImage) 25 | { 26 | var result = _carImageService.Add(file, carImage); 27 | if (result.Success) 28 | { 29 | return Ok(result); 30 | } 31 | else 32 | { 33 | return BadRequest(result); 34 | } 35 | } 36 | [HttpDelete("delete")] 37 | public IActionResult Delete([FromForm(Name = ("Id"))] int Id) 38 | { 39 | var carImage = _carImageService.Get(Id).Data; 40 | 41 | var result = _carImageService.Delete(carImage); 42 | if (result.Success) 43 | { 44 | return Ok(result); 45 | } 46 | else 47 | { 48 | return BadRequest(result); 49 | } 50 | } 51 | [HttpPut("update")] 52 | public IActionResult Update([FromForm(Name = ("Image"))] IFormFile file, [FromForm(Name = ("Id"))] int Id) 53 | { 54 | var carImage = _carImageService.Get(Id).Data; 55 | var result = _carImageService.Update(file, carImage); 56 | if (result.Success) 57 | { 58 | return Ok(result); 59 | } 60 | else 61 | { 62 | return BadRequest(result); 63 | } 64 | } 65 | [HttpGet("getall")] 66 | public IActionResult GetAll() 67 | { 68 | var result = _carImageService.GetAll(); 69 | if (result.Success) 70 | { 71 | return Ok(result); 72 | } 73 | else 74 | { 75 | return BadRequest(result); 76 | } 77 | } 78 | [HttpGet("getbyid")] 79 | public IActionResult GetById(int carImageId) 80 | { 81 | var result = _carImageService.Get(carImageId); 82 | if (result.Success) 83 | { 84 | return Ok(result); 85 | } 86 | else 87 | { 88 | return BadRequest(result); 89 | } 90 | } 91 | [HttpGet("getcarimagedetails")] 92 | public IActionResult GetCarImageDetails() 93 | { 94 | var result = _carImageService.GetCarImageDetails(); 95 | if (result.Success) 96 | { 97 | return Ok(result); 98 | } 99 | else 100 | { 101 | return BadRequest(result); 102 | } 103 | } 104 | [HttpGet("getimagesbycarid")] 105 | public IActionResult GetImagesById(int id) 106 | { 107 | var result = _carImageService.GetImagesByCarId(id); 108 | if (result.Success) 109 | { 110 | return Ok(result); 111 | } 112 | return BadRequest(result); 113 | } 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /Business/Concrete/CarImageManager.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Core.Utilities.Results; 3 | using DataAccess.Abstract; 4 | using Entities.Concrete; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Linq; 9 | using Entities.DTOs; 10 | using Core.Utilities.Business; 11 | using Core.Utilities.Helpers; 12 | using System.IO; 13 | using Microsoft.AspNetCore.Http; 14 | using Core.Aspects.Autofac.Validation; 15 | using Business.ValidationRules.FluentValidation; 16 | using Business.Constants; 17 | using Core.Aspects.Autofac.Caching; 18 | 19 | namespace Business.Concrete 20 | { 21 | public class CarImageManager : ICarImageService 22 | { 23 | ICarImageDal _carImageDal; 24 | public CarImageManager(ICarImageDal carImageDal) 25 | { 26 | _carImageDal = carImageDal; 27 | } 28 | [ValidationAspect(typeof(CarImageValidator))] 29 | public IResult Add(IFormFile file, CarImage carImage) 30 | { 31 | 32 | IResult result = BusinessRules.Run(CheckImageLimitExceeded(carImage.CarId)); 33 | if (result != null) 34 | { 35 | return result; 36 | } 37 | carImage.ImagePath = FileHelper.Add(file); 38 | carImage.Date = DateTime.Now; 39 | _carImageDal.Add(carImage); 40 | return new SuccessResult(); 41 | } 42 | 43 | 44 | public IResult Delete(CarImage carImage) 45 | { 46 | FileHelper.Delete(carImage.ImagePath); 47 | _carImageDal.Delete(carImage); 48 | return new SuccessResult(Messages.Deleted); 49 | } 50 | [CacheAspect] 51 | public IDataResult> GetAll() 52 | { 53 | 54 | return new SuccessDataResult>(_carImageDal.GetAll()); 55 | } 56 | [CacheAspect] 57 | public IDataResult Get(int carImageId) 58 | { 59 | return new SuccessDataResult(_carImageDal.Get(p => p.Id == carImageId)); 60 | } 61 | 62 | public IDataResult> GetCarImageDetails() 63 | { 64 | return new SuccessDataResult>(_carImageDal.GetCarImageDetails()); 65 | } 66 | [ValidationAspect(typeof(CarImageValidator))] 67 | public IResult Update(IFormFile file, CarImage carImage) 68 | { 69 | carImage.ImagePath = FileHelper.Update(_carImageDal.Get(p => p.Id == carImage.Id).ImagePath, file); 70 | carImage.Date = DateTime.Now; 71 | _carImageDal.Update(carImage); 72 | return new SuccessResult(); 73 | } 74 | private IResult CheckImageLimitExceeded(int carid) 75 | { 76 | //1 arabanın en fazla 5 resmi olabilir dediğimiz kod bloğu. 77 | var carImageCount = _carImageDal.GetAll(p => p.CarId == carid).Count; 78 | if (carImageCount >= 5) 79 | { 80 | return new ErrorResult(Messages.CarImageLimitExceeded); 81 | } 82 | 83 | return new SuccessResult(); 84 | } 85 | private List CheckIfCarImageNull(int id) 86 | { 87 | //Arabanın resmi yoksa default resim koyulması için yazdığımzı kod bloğu. 88 | string path = @"\Images\bmw.jpg"; 89 | var result = _carImageDal.GetAll(c => c.CarId == id).Any(); 90 | if (!result) 91 | { 92 | return new List { new CarImage { CarId = id, ImagePath = path, Date = DateTime.Now } }; 93 | } 94 | return _carImageDal.GetAll(p => p.CarId == id); 95 | } 96 | 97 | public IDataResult> GetImagesByCarId(int id) 98 | { 99 | return new SuccessDataResult>(CheckIfCarImageNull(id)); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /WebAPI/Startup.cs: -------------------------------------------------------------------------------- 1 | using Business.Abstract; 2 | using Business.Concrete; 3 | using Core.DependencyResolvers; 4 | using Core.Extensions; 5 | using Core.Utilities.IoC; 6 | using Core.Utilities.Security.Encryption; 7 | using Core.Utilities.Security.JWT; 8 | using DataAccess.Abstract; 9 | using DataAccess.Concrete.EntityFramework; 10 | using Microsoft.AspNetCore.Authentication.JwtBearer; 11 | using Microsoft.AspNetCore.Builder; 12 | using Microsoft.AspNetCore.Hosting; 13 | using Microsoft.AspNetCore.Http; 14 | using Microsoft.AspNetCore.HttpsPolicy; 15 | using Microsoft.AspNetCore.Mvc; 16 | using Microsoft.Extensions.Configuration; 17 | using Microsoft.Extensions.DependencyInjection; 18 | using Microsoft.Extensions.Hosting; 19 | using Microsoft.Extensions.Logging; 20 | using Microsoft.IdentityModel.Tokens; 21 | using System; 22 | using System.Collections.Generic; 23 | using System.Linq; 24 | using System.Threading.Tasks; 25 | 26 | namespace WebAPI 27 | { 28 | public class Startup 29 | { 30 | public Startup(IConfiguration configuration) 31 | { 32 | Configuration = configuration; 33 | } 34 | 35 | public IConfiguration Configuration { get; } 36 | 37 | // This method gets called by the runtime. Use this method to add services to the container. 38 | public void ConfigureServices(IServiceCollection services) 39 | { 40 | services.AddControllers(); 41 | //services.AddSingleton(); 42 | //services.AddSingleton(); 43 | //services.AddSingleton(); 44 | //services.AddSingleton(); 45 | //services.AddSingleton(); 46 | //services.AddSingleton(); 47 | //services.AddSingleton(); 48 | //services.AddSingleton(); 49 | //services.AddSingleton(); 50 | //services.AddSingleton(); 51 | //services.AddSingleton(); 52 | //services.AddSingleton(); 53 | services.AddCors(); 54 | var tokenOptions = Configuration.GetSection("TokenOptions").Get(); 55 | 56 | services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) 57 | .AddJwtBearer(options => 58 | { 59 | options.TokenValidationParameters = new TokenValidationParameters 60 | { 61 | ValidateIssuer = true, 62 | ValidateAudience = true, 63 | ValidateLifetime = true, 64 | ValidIssuer = tokenOptions.Issuer, 65 | ValidAudience = tokenOptions.Audience, 66 | ValidateIssuerSigningKey = true, 67 | IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey) 68 | }; 69 | }); 70 | services.AddDependencyResolvers(new ICoreModule[] { 71 | new CoreModule() 72 | }); 73 | 74 | } 75 | 76 | 77 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 78 | public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 79 | { 80 | if (env.IsDevelopment()) 81 | { 82 | app.UseDeveloperExceptionPage(); 83 | } 84 | app.UseCors(builder => builder.WithOrigins("http://localhost:59581").AllowAnyHeader().AllowAnyOrigin()); 85 | 86 | app.UseHttpsRedirection(); 87 | 88 | app.UseRouting(); 89 | 90 | app.UseAuthentication(); 91 | 92 | app.UseAuthorization(); 93 | 94 | app.UseEndpoints(endpoints => 95 | { 96 | endpoints.MapControllers(); 97 | }); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /DataAccess/Concrete/InMemory/InMemoryCarDal.cs: -------------------------------------------------------------------------------- 1 | using DataAccess.Abstract; 2 | using Entities.Concrete; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | using System.Text; 8 | 9 | namespace DataAccess.Concrete.InMemory 10 | { 11 | public class InMemoryCarDal : ICarDal 12 | { 13 | List _cars; 14 | List _brands; 15 | List _colors; 16 | 17 | public InMemoryCarDal() 18 | { 19 | _cars = new List() 20 | { 21 | new Car { Id = 1, BrandId = 1, ColorId = 1, ModelYear ="2018",DailyPrice=700,Description="Konfor ve rahatlık sevenler için."}, 22 | new Car { Id = 2, BrandId = 2, ColorId = 2, ModelYear = "2017",DailyPrice=500,Description="Konfor sevenler için."}, 23 | new Car { Id = 3, BrandId = 3, ColorId = 3, ModelYear = "2016",DailyPrice=400,Description="Hız sevenler için."}, 24 | new Car { Id = 4, BrandId = 4, ColorId = 4, ModelYear = "2015",DailyPrice=300,Description="Farklı araç sürmek isteyenler için."}, 25 | new Car { Id = 5, BrandId = 5, ColorId = 1, ModelYear = "2014",DailyPrice=200,Description="Her kesim için ideal."}, 26 | }; 27 | _brands = new List() 28 | { 29 | new Brand { Id = 1, BrandName = "Toyota" }, 30 | new Brand { Id = 2, BrandName = "Opel" }, 31 | new Brand { Id = 3, BrandName = "BMW" }, 32 | new Brand { Id = 4, BrandName = "Scoda" }, 33 | new Brand { Id = 5, BrandName = "Fiat" }, 34 | }; 35 | 36 | _colors = new List 37 | { 38 | new Color{Id=1,ColorName="Beyaz"}, 39 | new Color{Id=2,ColorName="Kırmızı"}, 40 | new Color{Id=3,ColorName="Mavi"}, 41 | new Color{Id=4,ColorName="Siyah"}, 42 | new Color{Id=5,ColorName="Lacivert"}, 43 | 44 | }; 45 | 46 | 47 | } 48 | 49 | public void Add(Car car) 50 | { 51 | _cars.Add(car); 52 | } 53 | 54 | 55 | 56 | public void Delete(Car car) 57 | { 58 | Car carToDelete = _cars.SingleOrDefault(p => p.Id == car.Id); 59 | _cars.Remove(carToDelete); 60 | } 61 | 62 | public Car Get(Expression> filter) 63 | { 64 | throw new NotImplementedException(); 65 | } 66 | 67 | public void GetAll() 68 | { 69 | int sira = 0; 70 | var result = (from c in _cars 71 | join b in _brands on c.BrandId equals b.Id 72 | join c2 in _colors on c.ColorId equals c2.Id 73 | orderby c.DailyPrice ascending, b.BrandName ascending 74 | select new CarDto { Id = c.Id, BrandName = b.BrandName, ColorName = c2.ColorName, ModelYear = c.ModelYear, DailyPrice = c.DailyPrice, Description = c.Description }); 75 | 76 | foreach (var car in result) 77 | { 78 | sira++; 79 | Console.WriteLine(sira + "-)" + " Marka: " + car.BrandName + " Renk: " + car.ColorName + " Model " + car.ModelYear + " Ücret : " + car.DailyPrice + " TL " + car.Description); 80 | 81 | } 82 | } 83 | 84 | public List GetAll(Expression> filter = null) 85 | { 86 | throw new NotImplementedException(); 87 | } 88 | 89 | public List GetAllByBrand(int brandId) 90 | { 91 | return _cars.Where(p => p.BrandId == brandId).ToList(); 92 | 93 | } 94 | 95 | public List GetAllByColor(int colorId) 96 | { 97 | return _cars.Where(p => p.ColorId == colorId).ToList(); 98 | } 99 | 100 | public List GetCarAsc() 101 | { 102 | throw new NotImplementedException(); 103 | } 104 | 105 | public List GetCarDesc() 106 | { 107 | throw new NotImplementedException(); 108 | } 109 | 110 | public List GetCarDetails() 111 | { 112 | throw new NotImplementedException(); 113 | } 114 | 115 | public void Update(Car car) 116 | { 117 | Car carToUpdate = _cars.SingleOrDefault(p => p.Id == car.Id); 118 | carToUpdate.BrandId = car.BrandId; 119 | carToUpdate.ColorId = car.ColorId; 120 | carToUpdate.ModelYear = car.ModelYear; 121 | carToUpdate.DailyPrice = car.DailyPrice; 122 | carToUpdate.Description = car.Description; 123 | 124 | 125 | } 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /WebAPI/Controllers/CarsController.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Http; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Business.Abstract; 4 | using Entities.Concrete; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace WebAPI.Controllers 11 | { 12 | [Route("api/[controller]")] 13 | [ApiController] 14 | public class CarsController : ControllerBase 15 | { 16 | ICarService _carService; 17 | public CarsController(ICarService carService) 18 | { 19 | _carService = carService; 20 | } 21 | [HttpPost("add")] 22 | public IActionResult Add(Car car) 23 | { 24 | var result = _carService.Add(car); 25 | if (result.Success) 26 | { 27 | return Ok(result); 28 | } 29 | else 30 | { 31 | return BadRequest(result); 32 | } 33 | } 34 | [HttpDelete("delete")] 35 | public IActionResult Delete(Car car) 36 | { 37 | var result = _carService.Delete(car); 38 | if (result.Success) 39 | { 40 | return Ok(result); 41 | } 42 | else 43 | { 44 | return BadRequest(result); 45 | } 46 | } 47 | [HttpPut("update")] 48 | public IActionResult Update(Car car) 49 | { 50 | var result = _carService.Update(car); 51 | if (result.Success) 52 | { 53 | return Ok(result); 54 | } 55 | else 56 | { 57 | return BadRequest(result); 58 | } 59 | } 60 | [HttpGet("getall")] 61 | public IActionResult GetAll() 62 | { 63 | var result = _carService.GetCarDetails(); 64 | if (result.Success) 65 | { 66 | return Ok(result); 67 | } 68 | else 69 | { 70 | return BadRequest(result); 71 | } 72 | } 73 | [HttpGet("getbyid")] 74 | public IActionResult GetById(int carId) 75 | { 76 | var result = _carService.GetById(carId); 77 | if (result.Success) 78 | { 79 | return Ok(result); 80 | } 81 | else 82 | { 83 | return BadRequest(result); 84 | } 85 | } 86 | [HttpGet("getbybrand")] 87 | public IActionResult GetByCategory(int brandId) 88 | { 89 | var result = _carService.GetCarsByBrandId(brandId); 90 | if (result.Success) 91 | { 92 | return Ok(result); 93 | } 94 | 95 | return BadRequest(result); 96 | } 97 | [HttpGet("getcardetails")] 98 | public IActionResult GetCarDetails() 99 | { 100 | var result = _carService.GetCarDetails(); 101 | if (result.Success) 102 | { 103 | return Ok(result); 104 | } 105 | else 106 | { 107 | return BadRequest(result); 108 | } 109 | } 110 | [HttpGet("getbydailyprice")] 111 | public IActionResult GetByDailyPrice(decimal min, decimal max) 112 | { 113 | var result = _carService.GetByDailyPrice(min, max); 114 | if (result.Success) 115 | { 116 | return Ok(result); 117 | } 118 | else 119 | { 120 | return BadRequest(result); 121 | } 122 | } 123 | [HttpGet("getcardesc")] 124 | public IActionResult GetCarDesc() 125 | { 126 | var result = _carService.GetCarDesc(); 127 | if (result.Success) 128 | { 129 | return Ok(result); 130 | } 131 | else 132 | { 133 | return BadRequest(result); 134 | } 135 | } 136 | [HttpGet("getcarasc")] 137 | public IActionResult GetCarAsc() 138 | { 139 | var result = _carService.GetCarAsc(); 140 | if (result.Success) 141 | { 142 | return Ok(result); 143 | } 144 | else 145 | { 146 | return BadRequest(result); 147 | } 148 | 149 | } 150 | [HttpGet("getcarsbybrandid")] 151 | public IActionResult GetCarsByBrandId(int id) 152 | { 153 | var result = _carService.GetCarsByBrandId(id); 154 | if (result.Success) 155 | { 156 | return Ok(result); 157 | } 158 | else 159 | { 160 | return BadRequest(result); 161 | } 162 | } 163 | [HttpGet("getcarsbycolorid")] 164 | public IActionResult GetCarsByColorId(int id) 165 | { 166 | var result = _carService.GetCarsByColorId(id); 167 | if (result.Success) 168 | { 169 | return Ok(result); 170 | } 171 | else 172 | { 173 | return BadRequest(result); 174 | } 175 | } 176 | } 177 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Car Rental Project 2 | ![](images/rentalcar.jpg) 3 | ### Proje Engin Demiroğ'un Yazılım Geliştirme Kampı süresince kendimizi geliştirmek adına her geçen gün daha da geliştirdiğimiz Car Rental yani Araç Kiralama projesidir. 4 | ## Öğrenilen 5 |
    6 |
  • Dependency Injection
  • 7 |
  • SOLID
  • 8 |
  • Web API
  • 9 |
  • Autofac
  • 10 |
  • AOP
  • 11 |
  • Fluent Validation
  • 12 |
  • JWT
  • 13 |
  • Caching
  • 14 |
  • Performance Management
  • 15 |
  • Transaction
  • 16 |
17 | 18 | ## Dependency Injection 19 | Dependency Injection türkçe anlamıyla Bağımlılık Enjeksiyonu anlamına gelir. Bu teknik SOLID prensiplerinin 5. harfi olan Dependency Inversion ayağının partneri diyebiliriz. Dependency Injection en basit mantıkla bir nesnenin bağlı olduğu diğer nesnelere ulaşmak için kullanılan bir tekniktir. Neden böyle bir yapıya ihtiyaç duyuyoruz diye sorarsak bağımlılıkları ortadan kaldırmak için diyebiliriz. Bu sayede ise; 20 |
    21 |
  • Gevşek Bağımlı uygulamalar tasarlayabilir(Loosely Coupled)
  • 22 |
  • Uygulama içerisinde değişmesi gereken yerler en aza indirgenebilir yani onlarca yerde değişiklik yapmak yerine tek bir çatıda yapılabilir.
  • 23 |
  • Yazılım Kalite kontrolü sağlanabilir.
  • 24 |
25 | 26 | ## SOLID 27 | ### Single Responsibility 28 | Single Responsibility en basit manada bir methodun içinde 2 işlem yapılamaz diyebiliriz. Katmanlı mimaride her katmanın bir görevi vardır siz Business katmanınında yazdığınız bir kodu DataAccess katmanında yazamazsınız eğer yazıyorsanız SOLID prensiplerini çiğniyorsunuz demektir. Her katman,sınıf,method vs. içinde tek bir iş yapılır. Buda bize Clean Code sunar. 29 | 30 | ### Open Closed 31 | Open Closed en basit manada tak-çıkar mantığı denilebilir. Open sınıfınıza yeni bir şeyler ekleyebilmenizi sağlar. Günü geldiğinde istekler değiştiğinde o isteklere cevap verebilmesi ve buna göre değişiklikler yapılmasını sağlar. Closed ise bir sınıfın temel özelliklerinin kapalı olmasını yani yeni gelen bir şey yüzünden o sınıfın özelliklerinin değişmemesi anlamını taşır. Yani yazdığınız projeye yeni bir özellik eklenebilmesi ve eklenen özellik ile hiç bir şeyin değişmemesi gerekir. 32 | 33 | ### Liskov Substitution 34 | Liskov Substitution en basit manada bir şey bir şeye benziyor diye aynı yerde kullanma demektir. Bir banka sistemini düşünün gerçek müşteri ve tüzel müşteriler vardır ama ikisi asla aynı değildir. Gerçek müşterinin TC Kimlik Numarası vardır ancak tüzel müşteriler yani firmaların böyle bir numarası yoktur siz müşteri sınıfında 2 ayrı müşterinin de bilgilerini tuttuğunuzda tüzel müşteride TC Kimlik Numarası kısmı boş geçiceksiniz buda istenilen bir durum asla değildir. 35 | 36 | ### Interface Segregation 37 | Interface Segregation en basit manada arayüz ayrılma ilkesidir. Bir şirketi düşünün bu şirkette yönetici,işçi ve robotların çalıştığını hayal edin ve bunların her biri bir sınıf olduğunu. Sizin tüm bunların dışında bir interface'iniz olsun ve methodları ise maaş ödeme çalışma ve yemek yeme olsun. Siz eğer bu interface'i hem robota hem yöneticiye hemde işçiye implemente ederseniz ortaya şöyle bir sonuç çıkar; 38 | #### Robot 39 |
    40 |
  • Maaş ödendi
  • 41 |
  • Yemek yendi
  • 42 |
  • Çalışma yapıldı
  • 43 |
44 | 45 | #### Yönetici 46 |
    47 |
  • Maaş ödendi
  • 48 |
  • Yemek yendi
  • 49 |
  • Çalışma yapıldı
  • 50 |
51 | 52 | #### İşçi 53 |
    54 |
  • Maaş ödendi
  • 55 |
  • Yemek yendi
  • 56 |
  • Çalışma yapıldı
  • 57 |
58 | 59 | Bir şeyi fark ettiniz mi robot maaş aldı yemek de yedi hemde çalıştı ancak robot maaş almaz ve yemek yemez öyle dimi ? İşte burada araya Interface Segregation geliyor yani arayüz ayrılma ilkesi. Biz bu yapıyı şöyle yapsak yemek yeme,çalışma ve maaş ödemeyi ayrı ayrı interface yapsak ve bunları ayrı ayrı sınıflara implemente etseydik şöyle bir sonuç çıkardı karşıya; 60 | #### Robot 61 |
    62 |
  • Çalışma yapıldı
  • 63 |
64 | 65 | #### Yönetici 66 |
    67 |
  • Maaş ödendi
  • 68 |
  • Yemek yendi
  • 69 |
  • Çalışma yapıldı
  • 70 |
71 | 72 | #### İşçi 73 |
    74 |
  • Maaş ödendi
  • 75 |
  • Yemek yendi
  • 76 |
  • Çalışma yapıldı
  • 77 |
78 | 79 | Bakın şimdi oldu işte. 80 | 81 | ### Dependency Inversion 82 | Dependency Inversion bir tasarım desenini kullanır oda yukarıda anlatmış olduğum Dependency Injection'dır. Buna da örnek verecek olursak bir bankayı düşünün 3 ayrı mevzuat hesabı olduğunu düşünün bunları çalıştırırken bir sınıfta 3'ünü de somut haliyle yani new'leyerek çağırıp ilgili fonksiyonu çalıştırmak zorundasınız ancak bunu yapmak yerine siz bir interface oluşturup onların referanslarını tutarsanız Dependency Injection yöntemiyle istenilen mevzuatları somut değilde soyut olarak çağırıp çalıştırabilirsiniz. Bunu yapma sebebimiz ise yarın bir gün farklı bir mevzuat geldiğinde hiç bir şey etkilenmeden yeni gelen mevzuatı da kullanabiliriz. 83 | 84 | ## Web API 85 | API, Türkçe anlamı “Uygulama Geliştirme Arayüzü” olan “Application Programming Interface” kelimelerinin baş harflerinden meydana gelen bir kelimedir. API sayesinde yazılım geliştiricileri, ellerindeki verileri yada işlevsellikleri istedikleri sınırlılıkta dış dünyayla paylaşabilmekte ve bu paylaşım sürecinde tüm kontrolleri ellerinde tutabilmektedirler. 86 | Web API kullanma ihtiyacı ise şu şekilde ortaya çıkıyor artık günümüzde cep telefon tablet gibi cihazların kullanım artışıyla sadece Web Siteleri yetersiz kalmaktadır bu yüzden Web API ile diğer cihazlardaki kullancı isteklerine de karşılık vermek amacıyla API ihtiyacı ortaya çıkmıştır. 87 | 88 | ## Autofac 89 | Autofac, .Net için yazılmış bir containerdır ve kullanımı oldukça kolay ve kullanışlıdır. IoC Container yerine kullanılabilir ancak aklımıza şu soru gelebilir zaten .Net'in içinde default olarak var olan bir kullanım varken neden bu gibi Containerlara ihtiyaç duyuyoruz diyebilirsiniz bunu şöyle açıklayabiliriz Autofac bize AOP yapmamızı sağlayan bir yapıdır ve bunun dışında yarın öbür gün farklı servis sağlayıcıları yada farklı API eklendiğini düşünecek olursak var olan yöntem biraz ilkel kalacaktır. 90 | 91 | ## Fluent Validation 92 | Fluent Validation, veri kuralları kütüphanesidir. Biz burada verilerin doğruluğunu teyit etmek için kullandığımız bir kütüphanedir. Daha açıklayıcı anlatıcak olursak tek bir çatı altında doğrulama kurallarını yazmamızı sağlar ve oldukça güvenlidir. Ancak çoğu insan iş kuralları ile doğrulama kurallarını karıştırır ikisinin arasındaki en temel fark doğrulama kuralları o verinin yapısıyla ilgilenir ancak iş kuralları yapıyla ilgilenmez iş kuralları örnek verecek olursak birine ehliyet verirken yazılı sınavdan geçti mi ? test sürüşünden geçti mi ? gibi soruların olduğu kurallardır doğrulama kuralları ise bir veri eklendiğini düşünün minumum 10 karakter gibi kuralların olduğu kısımdır. 93 | 94 | ## AOP(Aspect Oriented Programming) 95 | Türkçe anlamıyla Cephe Yönelimli Programlama anlamına gelir. Neden böyle bir teknolojiye ihtiyaç duyarız diyorsanız bunun sebebi ise şudur yazılım geliştirmede bazı bileşenler Croos Cutting Concerns yani uygulamayı dikine kesen ilgi alanları diyebiliriz, loglama,cache,doğrulama,performans yönetimi gibi bütün katmanlarda farklı katmanlarda bunları yapabiliyoruz yani AOP sayesinde Aspect kullanarak Attribute'ler ile kullanılabilir hale getiriyoruz. 96 | 97 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | [Dd]ebugPublic/ 19 | [Rr]elease/ 20 | [Rr]eleases/ 21 | x64/ 22 | x86/ 23 | [Aa][Rr][Mm]/ 24 | [Aa][Rr][Mm]64/ 25 | bld/ 26 | [Bb]in/ 27 | [Oo]bj/ 28 | [Ll]og/ 29 | 30 | # Visual Studio 2015/2017 cache/options directory 31 | .vs/ 32 | # Uncomment if you have tasks that create the project's static files in wwwroot 33 | #wwwroot/ 34 | 35 | # Visual Studio 2017 auto generated files 36 | Generated\ Files/ 37 | 38 | # MSTest test Results 39 | [Tt]est[Rr]esult*/ 40 | [Bb]uild[Ll]og.* 41 | 42 | # NUNIT 43 | *.VisualState.xml 44 | TestResult.xml 45 | 46 | # Build Results of an ATL Project 47 | [Dd]ebugPS/ 48 | [Rr]eleasePS/ 49 | dlldata.c 50 | 51 | # Benchmark Results 52 | BenchmarkDotNet.Artifacts/ 53 | 54 | # .NET Core 55 | project.lock.json 56 | project.fragment.lock.json 57 | artifacts/ 58 | 59 | # StyleCop 60 | StyleCopReport.xml 61 | 62 | # Files built by Visual Studio 63 | *_i.c 64 | *_p.c 65 | *_h.h 66 | *.ilk 67 | *.meta 68 | *.obj 69 | *.iobj 70 | *.pch 71 | *.pdb 72 | *.ipdb 73 | *.pgc 74 | *.pgd 75 | *.rsp 76 | *.sbr 77 | *.tlb 78 | *.tli 79 | *.tlh 80 | *.tmp 81 | *.tmp_proj 82 | *_wpftmp.csproj 83 | *.log 84 | *.vspscc 85 | *.vssscc 86 | .builds 87 | *.pidb 88 | *.svclog 89 | *.scc 90 | 91 | # Chutzpah Test files 92 | _Chutzpah* 93 | 94 | # Visual C++ cache files 95 | ipch/ 96 | *.aps 97 | *.ncb 98 | *.opendb 99 | *.opensdf 100 | *.sdf 101 | *.cachefile 102 | *.VC.db 103 | *.VC.VC.opendb 104 | 105 | # Visual Studio profiler 106 | *.psess 107 | *.vsp 108 | *.vspx 109 | *.sap 110 | 111 | # Visual Studio Trace Files 112 | *.e2e 113 | 114 | # TFS 2012 Local Workspace 115 | $tf/ 116 | 117 | # Guidance Automation Toolkit 118 | *.gpState 119 | 120 | # ReSharper is a .NET coding add-in 121 | _ReSharper*/ 122 | *.[Rr]e[Ss]harper 123 | *.DotSettings.user 124 | 125 | # JustCode is a .NET coding add-in 126 | .JustCode 127 | 128 | # TeamCity is a build add-in 129 | _TeamCity* 130 | 131 | # DotCover is a Code Coverage Tool 132 | *.dotCover 133 | 134 | # AxoCover is a Code Coverage Tool 135 | .axoCover/* 136 | !.axoCover/settings.json 137 | 138 | # Visual Studio code coverage results 139 | *.coverage 140 | *.coveragexml 141 | 142 | # NCrunch 143 | _NCrunch_* 144 | .*crunch*.local.xml 145 | nCrunchTemp_* 146 | 147 | # MightyMoose 148 | *.mm.* 149 | AutoTest.Net/ 150 | 151 | # Web workbench (sass) 152 | .sass-cache/ 153 | 154 | # Installshield output folder 155 | [Ee]xpress/ 156 | 157 | # DocProject is a documentation generator add-in 158 | DocProject/buildhelp/ 159 | DocProject/Help/*.HxT 160 | DocProject/Help/*.HxC 161 | DocProject/Help/*.hhc 162 | DocProject/Help/*.hhk 163 | DocProject/Help/*.hhp 164 | DocProject/Help/Html2 165 | DocProject/Help/html 166 | 167 | # Click-Once directory 168 | publish/ 169 | 170 | # Publish Web Output 171 | *.[Pp]ublish.xml 172 | *.azurePubxml 173 | # Note: Comment the next line if you want to checkin your web deploy settings, 174 | # but database connection strings (with potential passwords) will be unencrypted 175 | *.pubxml 176 | *.publishproj 177 | 178 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 179 | # checkin your Azure Web App publish settings, but sensitive information contained 180 | # in these scripts will be unencrypted 181 | PublishScripts/ 182 | 183 | # NuGet Packages 184 | *.nupkg 185 | # The packages folder can be ignored because of Package Restore 186 | **/[Pp]ackages/* 187 | # except build/, which is used as an MSBuild target. 188 | !**/[Pp]ackages/build/ 189 | # Uncomment if necessary however generally it will be regenerated when needed 190 | #!**/[Pp]ackages/repositories.config 191 | # NuGet v3's project.json files produces more ignorable files 192 | *.nuget.props 193 | *.nuget.targets 194 | 195 | # Microsoft Azure Build Output 196 | csx/ 197 | *.build.csdef 198 | 199 | # Microsoft Azure Emulator 200 | ecf/ 201 | rcf/ 202 | 203 | # Windows Store app package directories and files 204 | AppPackages/ 205 | BundleArtifacts/ 206 | Package.StoreAssociation.xml 207 | _pkginfo.txt 208 | *.appx 209 | 210 | # Visual Studio cache files 211 | # files ending in .cache can be ignored 212 | *.[Cc]ache 213 | # but keep track of directories ending in .cache 214 | !?*.[Cc]ache/ 215 | 216 | # Others 217 | ClientBin/ 218 | ~$* 219 | *~ 220 | *.dbmdl 221 | *.dbproj.schemaview 222 | *.jfm 223 | *.pfx 224 | *.publishsettings 225 | orleans.codegen.cs 226 | 227 | # Including strong name files can present a security risk 228 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 229 | #*.snk 230 | 231 | # Since there are multiple workflows, uncomment next line to ignore bower_components 232 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 233 | #bower_components/ 234 | 235 | # RIA/Silverlight projects 236 | Generated_Code/ 237 | 238 | # Backup & report files from converting an old project file 239 | # to a newer Visual Studio version. Backup files are not needed, 240 | # because we have git ;-) 241 | _UpgradeReport_Files/ 242 | Backup*/ 243 | UpgradeLog*.XML 244 | UpgradeLog*.htm 245 | ServiceFabricBackup/ 246 | *.rptproj.bak 247 | 248 | # SQL Server files 249 | *.mdf 250 | *.ldf 251 | *.ndf 252 | 253 | # Business Intelligence projects 254 | *.rdl.data 255 | *.bim.layout 256 | *.bim_*.settings 257 | *.rptproj.rsuser 258 | *- Backup*.rdl 259 | 260 | # Microsoft Fakes 261 | FakesAssemblies/ 262 | 263 | # GhostDoc plugin setting file 264 | *.GhostDoc.xml 265 | 266 | # Node.js Tools for Visual Studio 267 | .ntvs_analysis.dat 268 | node_modules/ 269 | 270 | # Visual Studio 6 build log 271 | *.plg 272 | 273 | # Visual Studio 6 workspace options file 274 | *.opt 275 | 276 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 277 | *.vbw 278 | 279 | # Visual Studio LightSwitch build output 280 | **/*.HTMLClient/GeneratedArtifacts 281 | **/*.DesktopClient/GeneratedArtifacts 282 | **/*.DesktopClient/ModelManifest.xml 283 | **/*.Server/GeneratedArtifacts 284 | **/*.Server/ModelManifest.xml 285 | _Pvt_Extensions 286 | 287 | # Paket dependency manager 288 | .paket/paket.exe 289 | paket-files/ 290 | 291 | # FAKE - F# Make 292 | .fake/ 293 | 294 | # JetBrains Rider 295 | .idea/ 296 | *.sln.iml 297 | 298 | # CodeRush personal settings 299 | .cr/personal 300 | 301 | # Python Tools for Visual Studio (PTVS) 302 | __pycache__/ 303 | *.pyc 304 | 305 | # Cake - Uncomment if you are using it 306 | # tools/** 307 | # !tools/packages.config 308 | 309 | # Tabs Studio 310 | *.tss 311 | 312 | # Telerik's JustMock configuration file 313 | *.jmconfig 314 | 315 | # BizTalk build output 316 | *.btp.cs 317 | *.btm.cs 318 | *.odx.cs 319 | *.xsd.cs 320 | 321 | # OpenCover UI analysis results 322 | OpenCover/ 323 | 324 | # Azure Stream Analytics local run output 325 | ASALocalRun/ 326 | 327 | # MSBuild Binary and Structured Log 328 | *.binlog 329 | 330 | # NVidia Nsight GPU debugger configuration file 331 | *.nvuser 332 | 333 | # MFractors (Xamarin productivity tool) working folder 334 | .mfractor/ 335 | 336 | # Local History for Visual Studio 337 | .localhistory/ 338 | 339 | # BeatPulse healthcheck temp database 340 | healthchecksdb -------------------------------------------------------------------------------- /ConsoleUI/Program.cs: -------------------------------------------------------------------------------- 1 | using Business.Concrete; 2 | using DataAccess.Concrete.EntityFramework; 3 | using DataAccess.Concrete.InMemory; 4 | using Entities.Concrete; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | 9 | 10 | namespace ConsoleUI 11 | { 12 | class Program 13 | { 14 | 15 | 16 | static void Main(string[] args) 17 | { 18 | CarManager carManager = new CarManager(new EfCarDal()); 19 | BrandManager brandManager = new BrandManager(new EfBrandDal()); 20 | ColorManager colorManager = new ColorManager(new EfColorDal()); 21 | UserManager userManager = new UserManager(new EfUserDal()); 22 | CustomerManager customerManager = new CustomerManager(new EfCustomerDal()); 23 | RentalManager rentalManager = new RentalManager(new EfRentalDal()); 24 | 25 | Tekrar: 26 | Console.WriteLine("********Rent A Car Sistemine Hoşgeldiniz********"); 27 | Console.WriteLine("1-)Kiralık Araç Listesi"); 28 | Console.WriteLine("2-)Marka Listesi"); 29 | Console.WriteLine("3-)Renk Listesi"); 30 | Console.WriteLine("4-)Kiralık Araç Ekle"); 31 | Console.WriteLine("5-)Marka Ekle"); 32 | Console.WriteLine("6-)Renk Ekle"); 33 | Console.WriteLine("7-)Araç Sil"); 34 | Console.WriteLine("8-)Araç Bilgisi Güncelleştir"); 35 | Console.WriteLine("9-)Fiyat Aralığındaki Araç Listesi"); 36 | Console.WriteLine("10-)Fiyata Göre Artan Araç Listesi"); 37 | Console.WriteLine("11-)Fiyata Göre Azalan Araç Listesi"); 38 | Console.WriteLine("12-)Marka Güncelle"); 39 | Console.WriteLine("13-)Renk Güncelle"); 40 | Console.WriteLine("14-)Kullanıcı Ekle"); 41 | Console.WriteLine("15-)Kullanıcı Sil"); 42 | Console.WriteLine("16-)Kullanıcı Güncelle"); 43 | Console.WriteLine("17-)Kullanıcı Listesi"); 44 | Console.WriteLine("18-)Müşteri Ekle"); 45 | Console.WriteLine("19-)Müşteri Sil"); 46 | Console.WriteLine("20-)Müşteri Güncelle"); 47 | Console.WriteLine("21-)Müşteri Listesi"); 48 | Console.WriteLine("22-)Araç Kirala"); 49 | Console.WriteLine("23-)Kiralanmış Araç Bilgilerini Güncelle"); 50 | Console.WriteLine("24-)Kiralanmış Araç Listesi"); 51 | Console.WriteLine("25-)Araç Teslim Et"); 52 | Console.WriteLine("26-)Programı Sonlandır"); 53 | string anaMenu; 54 | int secim = 0; 55 | try 56 | { 57 | secim = Convert.ToInt32(Console.ReadLine()); 58 | } 59 | catch (Exception) 60 | { 61 | Console.WriteLine("Yanlış karakter girdiniz !"); 62 | } 63 | switch (secim) 64 | { 65 | case 1: 66 | { 67 | var result = carManager.GetCarDetails(); 68 | if (result.Success) 69 | { 70 | Console.WriteLine("**************Araç Listesi**************"); 71 | foreach (var carDto in carManager.GetCarDetails().Data) 72 | { 73 | 74 | Console.WriteLine("Id:" + carDto.Id + "/" + carDto.BrandName + "/" + carDto.ColorName + "/" + carDto.ModelYear + "/" + carDto.DailyPrice + "/" + carDto.Description); 75 | Console.WriteLine("---------------------------------------------"); 76 | } 77 | } 78 | 79 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 80 | anaMenu = Console.ReadLine(); 81 | if (anaMenu == "e") 82 | { 83 | 84 | goto Tekrar; 85 | 86 | } 87 | 88 | 89 | 90 | break; 91 | } 92 | case 2: 93 | { 94 | var result = brandManager.GetAll(); 95 | if (result.Success) 96 | { 97 | Console.WriteLine("******************Marka Listesi******************"); 98 | foreach (var brand in brandManager.GetAll().Data) 99 | { 100 | Console.WriteLine("Id:" + brand.Id + "/" + brand.BrandName); 101 | Console.WriteLine("---------------------------------------------"); 102 | } 103 | } 104 | 105 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 106 | anaMenu = Console.ReadLine(); 107 | if (anaMenu == "e") 108 | { 109 | 110 | goto Tekrar; 111 | 112 | } 113 | break; 114 | } 115 | case 3: 116 | { 117 | Console.WriteLine("******************Renk Listesi******************"); 118 | var result = colorManager.GetAll(); 119 | if (result.Success) 120 | { 121 | foreach (var color in colorManager.GetAll().Data) 122 | { 123 | Console.WriteLine("Id:" + color.Id + "/" + color.ColorName); 124 | Console.WriteLine("---------------------------------------------"); 125 | } 126 | } 127 | 128 | 129 | 130 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 131 | anaMenu = Console.ReadLine(); 132 | if (anaMenu == "e") 133 | { 134 | 135 | goto Tekrar; 136 | 137 | } 138 | break; 139 | } 140 | case 4: 141 | { 142 | string modelYear, description; 143 | int brand = 0, color = 0, dailyPrice = 0; 144 | Console.WriteLine("Eklemek istediğiniz aracın bilgilerini giriniz"); 145 | Console.WriteLine("Markanın BrandId değerini giriniz."); 146 | brand = Convert.ToInt32(Console.ReadLine()); 147 | Console.WriteLine("Rengin ColorId değerini giriniz"); 148 | color = Convert.ToInt32(Console.ReadLine()); 149 | Console.WriteLine("Model yılınız giriniz"); 150 | modelYear = Console.ReadLine(); 151 | Console.WriteLine("Kiralama ücretini giriniz"); 152 | dailyPrice = Convert.ToInt32(Console.ReadLine()); 153 | Console.WriteLine("Açıklama giriniz"); 154 | description = Console.ReadLine(); 155 | Car car1 = new Car { BrandId = brand, ColorId = color, ModelYear = modelYear, DailyPrice = dailyPrice, Description = description }; 156 | carManager.Add(car1); 157 | Console.WriteLine("Araç başarılı bir şekilde sistem tarafından eklendi."); 158 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 159 | anaMenu = Console.ReadLine(); 160 | if (anaMenu == "e") 161 | { 162 | 163 | goto Tekrar; 164 | 165 | } 166 | 167 | 168 | break; 169 | } 170 | case 5: 171 | { 172 | string marka; 173 | Console.WriteLine("Eklemek istediğiniz markayı yazınız"); 174 | marka = Console.ReadLine(); 175 | Brand brand1 = new Brand { BrandName = marka }; 176 | brandManager.Add(brand1); 177 | Console.WriteLine("Marka ekleme işlemi başarılı şekilde yapıldı."); 178 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 179 | anaMenu = Console.ReadLine(); 180 | if (anaMenu == "e") 181 | { 182 | 183 | 184 | goto Tekrar; 185 | 186 | } 187 | break; 188 | } 189 | case 6: 190 | { 191 | string renk; 192 | Console.WriteLine("Eklemek istediğiniz rengi yazınız"); 193 | renk = Console.ReadLine(); 194 | Color color1 = new Color { ColorName = renk }; 195 | colorManager.Add(color1); 196 | Console.WriteLine("Renk ekleme işlemi başarılı şekilde yapıldı."); 197 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 198 | anaMenu = Console.ReadLine(); 199 | if (anaMenu == "e") 200 | { 201 | 202 | goto Tekrar; 203 | 204 | } 205 | break; 206 | } 207 | case 7: 208 | { 209 | 210 | int id = 0; 211 | Console.WriteLine("Silmek istediğiniz aracın Id değerini giriniz."); 212 | id = Convert.ToInt32(Console.ReadLine()); 213 | Car car2 = new Car { Id = id }; 214 | carManager.Delete(car2); 215 | Console.WriteLine("Silme işlemi başarıyla tamamlandı."); 216 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 217 | anaMenu = Console.ReadLine(); 218 | if (anaMenu == "e") 219 | { 220 | 221 | goto Tekrar; 222 | 223 | } 224 | 225 | 226 | break; 227 | } 228 | case 8: 229 | { 230 | string modelYear, description; 231 | int brand = 0, color = 0, dailyPrice = 0, id = 0; 232 | Console.WriteLine("Güncellemek istediğiniz aracın bilgilerini giriniz"); 233 | Console.WriteLine("Güncellemek istediğiniz aracın Id değerini giriniz."); 234 | id = Convert.ToInt32(Console.ReadLine()); 235 | Console.WriteLine("Markanın BrandId değerini giriniz."); 236 | brand = Convert.ToInt32(Console.ReadLine()); 237 | Console.WriteLine("Rengin ColorId değerini giriniz"); 238 | color = Convert.ToInt32(Console.ReadLine()); 239 | Console.WriteLine("Model yılınız giriniz"); 240 | modelYear = Console.ReadLine(); 241 | Console.WriteLine("Kiralama ücretini giriniz"); 242 | dailyPrice = Convert.ToInt32(Console.ReadLine()); 243 | Console.WriteLine("Açıklama giriniz"); 244 | description = Console.ReadLine(); 245 | Car car1 = new Car { Id = id, BrandId = brand, ColorId = color, ModelYear = modelYear, DailyPrice = dailyPrice, Description = description }; 246 | Console.WriteLine("Güncelleştirme işlemi başarıyla tamamlandı"); 247 | carManager.Update(car1); 248 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 249 | anaMenu = Console.ReadLine(); 250 | if (anaMenu == "e") 251 | { 252 | 253 | goto Tekrar; 254 | 255 | } 256 | break; 257 | } 258 | case 9: 259 | { 260 | 261 | int minMoney = 0, maxMoney = 0; 262 | Console.WriteLine("Kiralamak istediğiniz değer aralığını giriniz."); 263 | Console.WriteLine("Minumum ücreti giriniz."); 264 | minMoney = Convert.ToInt32(Console.ReadLine()); 265 | Console.WriteLine("Maxiumum ücreti giriniz."); 266 | maxMoney = Convert.ToInt32(Console.ReadLine()); 267 | var result = carManager.GetByDailyPrice(minMoney, maxMoney); 268 | if (result.Success) 269 | { 270 | foreach (var i in carManager.GetByDailyPrice(minMoney, maxMoney).Data) 271 | { 272 | Console.WriteLine("Id:" + i.Id + "/" + brandManager.GetById(i.BrandId).Data.BrandName + "/" + colorManager.GetById(i.ColorId).Data.ColorName + "/" + i.ModelYear + "/" + i.DailyPrice + "/" + i.Description); 273 | } 274 | } 275 | 276 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 277 | anaMenu = Console.ReadLine(); 278 | if (anaMenu == "e") 279 | { 280 | 281 | goto Tekrar; 282 | 283 | } 284 | break; 285 | } 286 | case 10: 287 | { 288 | var result = carManager.GetCarAsc(); 289 | if (result.Success) 290 | { 291 | foreach (var asc in carManager.GetCarAsc().Data) 292 | { 293 | Console.WriteLine("Id:" + asc.Id + "/" + asc.BrandName + "/" + asc.ColorName + "/" + asc.ModelYear + "/" + asc.DailyPrice + "/" + asc.Description); 294 | } 295 | } 296 | 297 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 298 | anaMenu = Console.ReadLine(); 299 | if (anaMenu == "e") 300 | { 301 | 302 | goto Tekrar; 303 | 304 | } 305 | break; 306 | } 307 | case 11: 308 | { 309 | var result = carManager.GetCarDesc(); 310 | if (result.Success) 311 | { 312 | foreach (var desc in carManager.GetCarDesc().Data) 313 | { 314 | Console.WriteLine("Id:" + desc.Id + "/" + desc.BrandName + "/" + desc.ColorName + "/" + desc.ModelYear + "/" + desc.DailyPrice + "/" + desc.Description); 315 | } 316 | } 317 | 318 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 319 | anaMenu = Console.ReadLine(); 320 | if (anaMenu == "e") 321 | { 322 | 323 | goto Tekrar; 324 | 325 | } 326 | break; 327 | } 328 | case 12: 329 | { 330 | string marka; 331 | int id = 0; 332 | Console.WriteLine("Id"); 333 | id = Convert.ToInt32(Console.ReadLine()); 334 | Console.WriteLine("Yeni markayı yazınız"); 335 | marka = Console.ReadLine(); 336 | Brand brand1 = new Brand { Id = id, BrandName = marka }; 337 | brandManager.Update(brand1); 338 | Console.WriteLine("Marka güncelleme işlemi başarılı şekilde yapıldı."); 339 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 340 | anaMenu = Console.ReadLine(); 341 | if (anaMenu == "e") 342 | { 343 | 344 | 345 | goto Tekrar; 346 | 347 | } 348 | 349 | break; 350 | } 351 | case 13: 352 | { 353 | string renk; 354 | int id = 0; 355 | Console.WriteLine("Güncellemek istediğiniz rengin Id değerini giriniz."); 356 | id = Convert.ToInt32(Console.ReadLine()); 357 | Console.WriteLine("Yeni rengi yazınız"); 358 | renk = Console.ReadLine(); 359 | Color color1 = new Color { Id = id, ColorName = renk }; 360 | colorManager.Update(color1); 361 | Console.WriteLine("Renk güncelleme işlemi başarılı şekilde yapıldı."); 362 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 363 | anaMenu = Console.ReadLine(); 364 | if (anaMenu == "e") 365 | { 366 | 367 | goto Tekrar; 368 | 369 | } 370 | break; 371 | } 372 | case 14: 373 | { 374 | string ad, soyad, email; 375 | byte[] password; 376 | Console.WriteLine("Kullanıcı adı giriniz."); 377 | ad = Console.ReadLine(); 378 | Console.WriteLine("Kullanıcı soyadı giriniz."); 379 | soyad = Console.ReadLine(); 380 | Console.WriteLine("Email giriniz."); 381 | email = Console.ReadLine(); 382 | Console.WriteLine("Şifre giriniz."); 383 | password = Convert.FromBase64String(Console.ReadLine()); 384 | User user = new User { FirstName = ad, LastName = soyad, Email = email, PasswordHash = password }; 385 | userManager.Add(user); 386 | Console.WriteLine("Kullanıcı başarıyla eklendi."); 387 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 388 | anaMenu = Console.ReadLine(); 389 | if (anaMenu == "e") 390 | { 391 | 392 | goto Tekrar; 393 | 394 | } 395 | 396 | break; 397 | } 398 | case 15: 399 | { 400 | int id = 0; 401 | Console.WriteLine("Silmek istediğiniz kullanıcının Id değerini giriniz."); 402 | id = Convert.ToInt32(Console.ReadLine()); 403 | User user = new User { Id = id }; 404 | userManager.Delete(user); 405 | Console.WriteLine("Kullanıcı başarıyla silindi."); 406 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 407 | anaMenu = Console.ReadLine(); 408 | if (anaMenu == "e") 409 | { 410 | 411 | goto Tekrar; 412 | 413 | } 414 | break; 415 | } 416 | case 16: 417 | { 418 | int id = 0; 419 | string ad, soyad, email; 420 | byte[] password; 421 | Console.WriteLine("Güncellemek istediğiniz kullanıcının Id değerini giriniz."); 422 | id = Convert.ToInt32(Console.ReadLine()); 423 | Console.WriteLine("Kullanıcı adı giriniz."); 424 | ad = Console.ReadLine(); 425 | Console.WriteLine("Kullanıcı soyadı giriniz."); 426 | soyad = Console.ReadLine(); 427 | Console.WriteLine("Email giriniz."); 428 | email = Console.ReadLine(); 429 | Console.WriteLine("Şifre giriniz."); 430 | password = Convert.FromBase64String(Console.ReadLine()); 431 | User user = new User { FirstName = ad, LastName = soyad, Email = email, PasswordHash = password }; 432 | userManager.Update(user); 433 | Console.WriteLine("Kullanıcı bilgileri başarıyla güncellenmiştir."); 434 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 435 | anaMenu = Console.ReadLine(); 436 | if (anaMenu == "e") 437 | { 438 | 439 | goto Tekrar; 440 | 441 | } 442 | break; 443 | } 444 | case 17: 445 | { 446 | foreach (var user in userManager.GetAll().Data) 447 | { 448 | Console.WriteLine("Id:" + user.Id + "/" + user.FirstName + "/" + user.LastName + "/" + user.Email + "/" + user.PasswordHash); 449 | Console.WriteLine("---------------------------------------------"); 450 | } 451 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 452 | anaMenu = Console.ReadLine(); 453 | if (anaMenu == "e") 454 | { 455 | 456 | goto Tekrar; 457 | 458 | } 459 | break; 460 | } 461 | case 18: 462 | { 463 | int userId; 464 | string companyName; 465 | Console.WriteLine("Eklemek istediğiniz müşterinin kullanıcı Id değerini giriniz."); 466 | userId = Convert.ToInt32(Console.ReadLine()); 467 | Console.WriteLine("Şirket adını giriniz."); 468 | companyName = Console.ReadLine(); 469 | Customer customer = new Customer { UserId = userId, CompanyName = companyName }; 470 | customerManager.Add(customer); 471 | Console.WriteLine("Müşteri başarıyla eklendi."); 472 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 473 | anaMenu = Console.ReadLine(); 474 | if (anaMenu == "e") 475 | { 476 | 477 | goto Tekrar; 478 | 479 | } 480 | break; 481 | } 482 | case 19: 483 | { 484 | int id = 0; 485 | Console.WriteLine("Silmek istediğiniz müşterinin Id değerini giriniz."); 486 | id = Convert.ToInt32(Console.ReadLine()); 487 | Customer customer = new Customer { Id = id }; 488 | customerManager.Delete(customer); 489 | Console.WriteLine("Müşteri başarıyla silindi."); 490 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 491 | anaMenu = Console.ReadLine(); 492 | if (anaMenu == "e") 493 | { 494 | 495 | goto Tekrar; 496 | 497 | } 498 | break; 499 | } 500 | case 20: 501 | { 502 | int userId, id; 503 | string companyName; 504 | Console.WriteLine("Güncellemek istediğiniz müşterinin Id değerini giriniz."); 505 | id = Convert.ToInt32(Console.ReadLine()); 506 | Console.WriteLine("Güncellemek istediğiniz müşterinin kullanıcı Id değerini giriniz."); 507 | userId = Convert.ToInt32(Console.ReadLine()); 508 | Console.WriteLine("Şirket adını giriniz."); 509 | companyName = Console.ReadLine(); 510 | Customer customer = new Customer { Id = id, UserId = userId, CompanyName = companyName }; 511 | customerManager.Update(customer); 512 | Console.WriteLine("Müşteri bilgileri başarıyla güncellendi."); 513 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 514 | anaMenu = Console.ReadLine(); 515 | if (anaMenu == "e") 516 | { 517 | 518 | goto Tekrar; 519 | 520 | } 521 | break; 522 | 523 | } 524 | case 21: 525 | { 526 | foreach (var customer in customerManager.GetCustomerDetails().Data) 527 | { 528 | Console.WriteLine("Id:" + customer.Id + "/" + customer.FirstName + "/" + customer.LastName + "/" + customer.Email + "/" + customer.Password + "/" + customer.CompanyName); 529 | Console.WriteLine("---------------------------------------------"); 530 | } 531 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 532 | anaMenu = Console.ReadLine(); 533 | if (anaMenu == "e") 534 | { 535 | 536 | goto Tekrar; 537 | 538 | } 539 | break; 540 | } 541 | case 22: 542 | { 543 | DateTime rentDate, returnDate; 544 | int carId = 0, customerId = 0; 545 | Console.WriteLine("Kiralamak istediğiniz aracın Id değerini giriniz."); 546 | carId = Convert.ToInt32(Console.ReadLine()); 547 | Console.WriteLine("Kiralamak istediğiniz müşterinin Id değerini giriniz."); 548 | customerId = Convert.ToInt32(Console.ReadLine()); 549 | Console.WriteLine("Başlangıç tarihini giriniz."); 550 | rentDate = DateTime.Parse(Console.ReadLine()); 551 | Console.WriteLine("Bitiş tarihini giriniz."); 552 | returnDate = DateTime.Parse(Console.ReadLine()); 553 | Rental rental = new Rental { CarId = carId, CustomerId = customerId, RentDate = rentDate, ReturnDate = returnDate }; 554 | var result2 = rentalManager.GetById(carId); 555 | if (result2.Success) 556 | { 557 | Console.WriteLine("Bu araç zaten kiralandı."); 558 | } 559 | else 560 | { 561 | 562 | rentalManager.Add(rental); 563 | 564 | 565 | } 566 | 567 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 568 | anaMenu = Console.ReadLine(); 569 | if (anaMenu == "e") 570 | { 571 | 572 | goto Tekrar; 573 | 574 | } 575 | break; 576 | } 577 | case 23: 578 | { 579 | DateTime rentDate, returnDate; 580 | int carId = 0, customerId = 0; 581 | Console.WriteLine("Güncellemek istediğiniz aracın Id değerini giriniz."); 582 | carId = Convert.ToInt32(Console.ReadLine()); 583 | Console.WriteLine("Güncelemek istediğiniz müşterinin Id değerini giriniz."); 584 | customerId = Convert.ToInt32(Console.ReadLine()); 585 | Console.WriteLine("Başlangıç tarihini giriniz."); 586 | rentDate = DateTime.Parse(Console.ReadLine()); 587 | Console.WriteLine("Bitiş tarihini giriniz."); 588 | returnDate = DateTime.Parse(Console.ReadLine()); 589 | Rental rental = new Rental { CarId = carId, CustomerId = customerId, RentDate = rentDate, ReturnDate = returnDate }; 590 | var result = rentalManager.Update(rental); 591 | if (result.Success) 592 | { 593 | rentalManager.Update(rental); 594 | 595 | } 596 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 597 | anaMenu = Console.ReadLine(); 598 | if (anaMenu == "e") 599 | { 600 | 601 | goto Tekrar; 602 | 603 | } 604 | break; 605 | } 606 | case 24: 607 | { 608 | Console.WriteLine("**************Kiralanmış Araç Listesi**************"); 609 | foreach (var rentalDto in rentalManager.GetRentalDetails().Data) 610 | { 611 | Console.WriteLine("Id:" + rentalDto.Id + "/" + rentalDto.FirstName + "/" + rentalDto.LastName + "/" + rentalDto.RentDate + "/" + rentalDto.RentDate + "/" + rentalDto.BrandName + "/" + rentalDto.ColorName + "/" + rentalDto.ModelYear + "/" + rentalDto.DailyPrice + "/" + rentalDto.Description + "/" + rentalDto.CompanyName); 612 | Console.WriteLine("---------------------------------------------"); 613 | } 614 | break; 615 | } 616 | case 25: 617 | { 618 | int carId, id; 619 | Console.WriteLine("Teslim etmek istediğiniz kiralık araç Id değerini giriniz."); 620 | id = Convert.ToInt32(Console.ReadLine()); 621 | Console.WriteLine("Teslim etmek istediğiniz aracın Id değerini giriniz."); 622 | carId = Convert.ToInt32(Console.ReadLine()); 623 | Rental rental = new Rental { Id = id, CarId = carId }; 624 | var result = rentalManager.GetById(carId); 625 | if (result.Success) 626 | { 627 | rentalManager.Delete(rental); 628 | } 629 | else 630 | { 631 | Console.WriteLine("Böyle bir araç kaydı bulunmamaktadır."); 632 | } 633 | Console.WriteLine("Ana menüye dönmek ister misiniz? Evet==e||Hayır==h"); 634 | anaMenu = Console.ReadLine(); 635 | if (anaMenu == "e") 636 | { 637 | 638 | goto Tekrar; 639 | 640 | } 641 | break; 642 | } 643 | case 26: 644 | { 645 | Console.WriteLine("Bir tuşa basın..."); 646 | Environment.Exit(0); 647 | break; 648 | } 649 | 650 | 651 | 652 | default: 653 | { 654 | Console.WriteLine("Yanlış seçim lütfen tekrar deneyiniz !"); 655 | goto Tekrar; 656 | 657 | } 658 | } 659 | 660 | 661 | 662 | } 663 | 664 | } 665 | } 666 | --------------------------------------------------------------------------------