diff --git a/BookAPI/BookAPI.csproj b/BookAPI/BookAPI.csproj
new file mode 100644
index 0000000..6acfe25
--- /dev/null
+++ b/BookAPI/BookAPI.csproj
@@ -0,0 +1,21 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
diff --git a/BookAPI/BookAPI.sln b/BookAPI/BookAPI.sln
new file mode 100644
index 0000000..2dea4e5
--- /dev/null
+++ b/BookAPI/BookAPI.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33103.184
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BookAPI", "BookAPI.csproj", "{FE52426A-BCF6-48AA-9441-63448C8FD5D8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FE52426A-BCF6-48AA-9441-63448C8FD5D8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {B6210FC6-C5EE-459E-ADC7-0D07807156F6}
+ EndGlobalSection
+EndGlobal
diff --git a/BookAPI/Controllers/AuthorController.cs b/BookAPI/Controllers/AuthorController.cs
new file mode 100644
index 0000000..2e3664c
--- /dev/null
+++ b/BookAPI/Controllers/AuthorController.cs
@@ -0,0 +1,99 @@
+using AutoMapper;
+using BookAPI.Dto;
+using BookAPI.Model;
+using BookAPI.Service.Implementation;
+using BookAPI.Service.Interface;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System.Net;
+
+namespace BookAPI.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class AuthorController : ControllerBase
+ {
+ private readonly IAuthorRepository _authorRepository;
+ private readonly IMapper _mapper;
+
+ public AuthorController(IAuthorRepository authorRepository, IMapper mapper)
+ {
+ _authorRepository = authorRepository;
+ _mapper = mapper;
+ }
+
+ [HttpPost]
+ public async Task> CreateAuthor(CreateAuthor createAuthor)
+ {
+ try
+ {
+ var author = _mapper.Map(createAuthor); // map CreateAuthor to Author
+ await _authorRepository.AddAsync(author);
+ var result = _mapper.Map(author);
+ return new ApiResponse { StatusCode = HttpStatusCode.Created, IsSuccess = true, Result = result };
+ }
+ catch (Exception ex)
+ {
+ var errors = new List { ex.Message };
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet("{id}")]
+ public async Task> GetAuthorById(int id)
+ {
+ try
+ {
+ var author = await _authorRepository.GetByIdAsync(id);
+ if (author == null)
+ {
+ return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false };
+ }
+ var result = _mapper.Map(author);
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = result };
+ }
+ catch (Exception ex)
+ {
+ var errors = new List { ex.Message };
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet]
+ public async Task> GetAllAuthors()
+ {
+ try
+ {
+ var authors = await _authorRepository.GetAllAsync();
+ var result = _mapper.Map>(authors);
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = result };
+ }
+ catch (Exception ex)
+ {
+ var errors = new List { ex.Message };
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet("{id}/books")]
+ public async Task> GetBooksAttachedToAnAuthor(int id)
+ {
+ try
+ {
+ var books = await _authorRepository.GetBooksAttachedToAuthor(id);
+ if (books == null)
+ {
+ return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false };
+ }
+ var result = _mapper.Map>(books);
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = result };
+ }
+ catch (Exception ex)
+ {
+ var errors = new List { ex.Message };
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+ }
+
+}
diff --git a/BookAPI/Controllers/BookController.cs b/BookAPI/Controllers/BookController.cs
new file mode 100644
index 0000000..5065fc7
--- /dev/null
+++ b/BookAPI/Controllers/BookController.cs
@@ -0,0 +1,82 @@
+using AutoMapper;
+using BookAPI.Dto;
+using BookAPI.Model;
+using BookAPI.Service.Interface;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System.Net;
+
+namespace BookAPI.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class BookController : ControllerBase
+ {
+ private readonly IRepository _bookRepository;
+ private readonly IMapper _mapper;
+
+ public BookController(IRepository bookRepository, IMapper mapper)
+ {
+ _bookRepository = bookRepository;
+ _mapper = mapper;
+ }
+
+ [HttpPost("CreateBook")]
+ public async Task> CreateBook(CreateBook createBook)
+ {
+ var errors = new List();
+ try
+ {
+ var book = _mapper.Map(createBook);
+ await _bookRepository.AddAsync(book);
+ var createdBook = _mapper.Map(book); // map Book to CreateBook
+ return new ApiResponse { StatusCode = HttpStatusCode.Created, IsSuccess = true, Result = createdBook };
+ }
+ catch (Exception ex)
+ {
+ errors.Add(ex.Message);
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet("{id}")]
+ public async Task> GetBookById(int id)
+ {
+ var errors = new List();
+ try
+ {
+ var book = await _bookRepository.GetByIdAsync(id);
+ if (book == null)
+ {
+ errors.Add($"Book with id {id} not found");
+ return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false, ErrorMessages = errors };
+ }
+ var thebook = _mapper.Map(book);
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thebook };
+ }
+ catch (Exception ex)
+ {
+ errors.Add(ex.Message);
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet]
+ public async Task> GetAllBooks()
+ {
+ var errors = new List();
+ try
+ {
+ var books = await _bookRepository.GetAllAsync();
+ var thebooks = _mapper.Map>(books);
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thebooks };
+ }
+ catch (Exception ex)
+ {
+ errors.Add(ex.Message);
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+ }
+
+ }
diff --git a/BookAPI/Controllers/PublisherController.cs b/BookAPI/Controllers/PublisherController.cs
new file mode 100644
index 0000000..5a9c9b4
--- /dev/null
+++ b/BookAPI/Controllers/PublisherController.cs
@@ -0,0 +1,110 @@
+using AutoMapper;
+using BookAPI.Dto;
+using BookAPI.Model;
+using BookAPI.Service.Implementation;
+using BookAPI.Service.Interface;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using System.Net;
+
+namespace BookAPI.Controllers
+{
+ [Route("api/[controller]")]
+ [ApiController]
+ public class PublisherController : ControllerBase
+ {
+ private readonly IPublisherRepository _publisherRepository;
+ private readonly IMapper _mapper;
+
+ public PublisherController(IPublisherRepository publisherRepository, IMapper mapper)
+ {
+ _publisherRepository = publisherRepository;
+ _mapper = mapper;
+ }
+
+ [HttpPost]
+ public async Task> CreatePublisher(CreatePublisher createPublisher)
+ {
+ var errors = new List();
+ try
+ {
+ var publisher = _mapper.Map(createPublisher);
+ await _publisherRepository.AddAsync(publisher);
+ var createdPublisher = _mapper.Map(publisher);
+
+ return new ApiResponse { StatusCode = HttpStatusCode.Created, IsSuccess = true, Result = createdPublisher };
+ }
+ catch (Exception ex)
+ {
+ errors.Add(ex.Message);
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet("{id}")]
+ public async Task> GetPublisher(int id)
+ {
+ var errors = new List();
+ try
+ {
+ var publisher = await _publisherRepository.GetByIdAsync(id);
+ if (publisher == null)
+ {
+ errors.Add($"Publisher with id {id} not found");
+ return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false, ErrorMessages = errors };
+ }
+ var thePublisher = _mapper.Map(publisher);
+
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thePublisher };
+ }
+ catch (Exception ex)
+ {
+ errors.Add(ex.Message);
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet]
+ public async Task> GetAllPublishers()
+ {
+ var errors = new List();
+ try
+ {
+ var publishers = await _publisherRepository.GetAllAsync();
+ var thePublishers = _mapper.Map>(publishers);
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = thePublishers };
+ }
+ catch (Exception ex)
+ {
+ errors.Add(ex.Message);
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ [HttpGet("{id}/authors")]
+ public async Task> GetAuthorsAttachedToAPublisher(int id)
+ {
+ var errors = new List();
+ try
+ {
+ var publisher = await _publisherRepository.GetByIdAsync(id);
+ if (publisher == null)
+ {
+ errors.Add($"Publisher with id {id} not found");
+ return new ApiResponse { StatusCode = HttpStatusCode.NotFound, IsSuccess = false, ErrorMessages = errors };
+ }
+ var authors = await _publisherRepository.GetAuthorsAttachedToPublisher(id);
+ var theAuthors = _mapper.Map>(authors);
+
+ return new ApiResponse { StatusCode = HttpStatusCode.OK, IsSuccess = true, Result = theAuthors };
+ }
+ catch (Exception ex)
+ {
+ errors.Add(ex.Message);
+ return new ApiResponse { StatusCode = HttpStatusCode.InternalServerError, IsSuccess = false, ErrorMessages = errors };
+ }
+ }
+
+ }
+
+ }
diff --git a/BookAPI/Data/ApplicationDbContext.cs b/BookAPI/Data/ApplicationDbContext.cs
new file mode 100644
index 0000000..fa7005c
--- /dev/null
+++ b/BookAPI/Data/ApplicationDbContext.cs
@@ -0,0 +1,15 @@
+using BookAPI.Model;
+using Microsoft.EntityFrameworkCore;
+
+namespace BookAPI.Data
+{
+ public class ApplicationDbContext : DbContext
+ {
+ public ApplicationDbContext(DbContextOptions options) : base(options)
+ {
+ }
+ public DbSet Books { get; set; }
+ public DbSet Publishers { get; set; }
+ public DbSet Authors { get; set; }
+ }
+}
diff --git a/BookAPI/Dto/CreateAuthor.cs b/BookAPI/Dto/CreateAuthor.cs
new file mode 100644
index 0000000..45a797d
--- /dev/null
+++ b/BookAPI/Dto/CreateAuthor.cs
@@ -0,0 +1,8 @@
+namespace BookAPI.Dto
+{
+ public class CreateAuthor
+ {
+ public string Name { get; set; }
+ public int PublisherId { get; set; }
+ }
+}
diff --git a/BookAPI/Dto/CreateBook.cs b/BookAPI/Dto/CreateBook.cs
new file mode 100644
index 0000000..78e497a
--- /dev/null
+++ b/BookAPI/Dto/CreateBook.cs
@@ -0,0 +1,14 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace BookAPI.Dto
+{
+ public class CreateBook
+ {
+ public string Title { get; set; }
+ public DateTime PublicationDate { get; set; }
+ [ForeignKey("Author")]
+ public int AuthorId { get; set; }
+ [ForeignKey("Publisher")]
+ public int PublisherId { get; set; }
+ }
+}
diff --git a/BookAPI/Dto/CreatePublisher.cs b/BookAPI/Dto/CreatePublisher.cs
new file mode 100644
index 0000000..060442d
--- /dev/null
+++ b/BookAPI/Dto/CreatePublisher.cs
@@ -0,0 +1,8 @@
+namespace BookAPI.Dto
+{
+ public class CreatePublisher
+ {
+ public string Name { get; set; }
+ public string Address { get; set; }
+ }
+}
diff --git a/BookAPI/Helper/Automapper.cs b/BookAPI/Helper/Automapper.cs
new file mode 100644
index 0000000..47efa35
--- /dev/null
+++ b/BookAPI/Helper/Automapper.cs
@@ -0,0 +1,16 @@
+using AutoMapper;
+using BookAPI.Dto;
+using BookAPI.Model;
+
+namespace BookAPI.AutoMapper
+{
+ public class Automapper : Profile
+ {
+ public Automapper()
+ {
+ CreateMap().ReverseMap();
+ CreateMap().ReverseMap();
+ CreateMap().ReverseMap();
+ }
+ }
+}
diff --git a/BookAPI/Migrations/20230310094639_initial.Designer.cs b/BookAPI/Migrations/20230310094639_initial.Designer.cs
new file mode 100644
index 0000000..232dce7
--- /dev/null
+++ b/BookAPI/Migrations/20230310094639_initial.Designer.cs
@@ -0,0 +1,140 @@
+//
+using System;
+using BookAPI.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace BookAPI.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20230310094639_initial")]
+ partial class initial
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
+
+ modelBuilder.Entity("BookAPI.Model.Author", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PublisherId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PublisherId");
+
+ b.ToTable("Authors");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Book", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AuthorId")
+ .HasColumnType("int");
+
+ b.Property("PublicationDate")
+ .HasColumnType("datetime2");
+
+ b.Property("PublisherId")
+ .HasColumnType("int");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuthorId");
+
+ b.HasIndex("PublisherId");
+
+ b.ToTable("Books");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Publisher", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Address")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Publishers");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Author", b =>
+ {
+ b.HasOne("BookAPI.Model.Publisher", "Publisher")
+ .WithMany("Authors")
+ .HasForeignKey("PublisherId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Publisher");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Book", b =>
+ {
+ b.HasOne("BookAPI.Model.Author", "Author")
+ .WithMany("Books")
+ .HasForeignKey("AuthorId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BookAPI.Model.Publisher", null)
+ .WithMany("Books")
+ .HasForeignKey("PublisherId");
+
+ b.Navigation("Author");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Author", b =>
+ {
+ b.Navigation("Books");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Publisher", b =>
+ {
+ b.Navigation("Authors");
+
+ b.Navigation("Books");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/BookAPI/Migrations/20230310094639_initial.cs b/BookAPI/Migrations/20230310094639_initial.cs
new file mode 100644
index 0000000..cc5fed5
--- /dev/null
+++ b/BookAPI/Migrations/20230310094639_initial.cs
@@ -0,0 +1,101 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace BookAPI.Migrations
+{
+ public partial class initial : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Publishers",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Name = table.Column(type: "nvarchar(max)", nullable: false),
+ Address = table.Column(type: "nvarchar(max)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Publishers", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Authors",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Name = table.Column(type: "nvarchar(max)", nullable: false),
+ PublisherId = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Authors", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Authors_Publishers_PublisherId",
+ column: x => x.PublisherId,
+ principalTable: "Publishers",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Books",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("SqlServer:Identity", "1, 1"),
+ Title = table.Column(type: "nvarchar(max)", nullable: false),
+ PublicationDate = table.Column(type: "datetime2", nullable: false),
+ AuthorId = table.Column(type: "int", nullable: false),
+ PublisherId = table.Column(type: "int", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Books", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Books_Authors_AuthorId",
+ column: x => x.AuthorId,
+ principalTable: "Authors",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ table.ForeignKey(
+ name: "FK_Books_Publishers_PublisherId",
+ column: x => x.PublisherId,
+ principalTable: "Publishers",
+ principalColumn: "Id");
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Authors_PublisherId",
+ table: "Authors",
+ column: "PublisherId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Books_AuthorId",
+ table: "Books",
+ column: "AuthorId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Books_PublisherId",
+ table: "Books",
+ column: "PublisherId");
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "Books");
+
+ migrationBuilder.DropTable(
+ name: "Authors");
+
+ migrationBuilder.DropTable(
+ name: "Publishers");
+ }
+ }
+}
diff --git a/BookAPI/Migrations/ApplicationDbContextModelSnapshot.cs b/BookAPI/Migrations/ApplicationDbContextModelSnapshot.cs
new file mode 100644
index 0000000..3ac95f3
--- /dev/null
+++ b/BookAPI/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -0,0 +1,138 @@
+//
+using System;
+using BookAPI.Data;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace BookAPI.Migrations
+{
+ [DbContext(typeof(ApplicationDbContext))]
+ partial class ApplicationDbContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "6.0.0")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128);
+
+ SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder, 1L, 1);
+
+ modelBuilder.Entity("BookAPI.Model.Author", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("PublisherId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("PublisherId");
+
+ b.ToTable("Authors");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Book", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("AuthorId")
+ .HasColumnType("int");
+
+ b.Property("PublicationDate")
+ .HasColumnType("datetime2");
+
+ b.Property("PublisherId")
+ .HasColumnType("int");
+
+ b.Property("Title")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuthorId");
+
+ b.HasIndex("PublisherId");
+
+ b.ToTable("Books");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Publisher", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property("Id"), 1L, 1);
+
+ b.Property("Address")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("nvarchar(max)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Publishers");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Author", b =>
+ {
+ b.HasOne("BookAPI.Model.Publisher", "Publisher")
+ .WithMany("Authors")
+ .HasForeignKey("PublisherId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Publisher");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Book", b =>
+ {
+ b.HasOne("BookAPI.Model.Author", "Author")
+ .WithMany("Books")
+ .HasForeignKey("AuthorId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("BookAPI.Model.Publisher", null)
+ .WithMany("Books")
+ .HasForeignKey("PublisherId");
+
+ b.Navigation("Author");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Author", b =>
+ {
+ b.Navigation("Books");
+ });
+
+ modelBuilder.Entity("BookAPI.Model.Publisher", b =>
+ {
+ b.Navigation("Authors");
+
+ b.Navigation("Books");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/BookAPI/Model/ApiResponse.cs b/BookAPI/Model/ApiResponse.cs
new file mode 100644
index 0000000..7cd1758
--- /dev/null
+++ b/BookAPI/Model/ApiResponse.cs
@@ -0,0 +1,12 @@
+using System.Net;
+
+namespace BookAPI.Model
+{
+ public class ApiResponse
+ {
+ public HttpStatusCode StatusCode { get; set; }
+ public bool IsSuccess { get; set; }
+ public List ErrorMessages { get; set; }
+ public object Result { get; set; }
+ }
+}
diff --git a/BookAPI/Model/Author.cs b/BookAPI/Model/Author.cs
new file mode 100644
index 0000000..228e864
--- /dev/null
+++ b/BookAPI/Model/Author.cs
@@ -0,0 +1,16 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace BookAPI.Model
+{
+ public class Author
+ {
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+ public string Name { get; set; }
+ [ForeignKey("Publisher")]
+ public int PublisherId { get; set; }
+ public Publisher Publisher { get; set; }
+ public ICollection Books { get; set; }
+ }
+
+}
\ No newline at end of file
diff --git a/BookAPI/Model/Book.cs b/BookAPI/Model/Book.cs
new file mode 100644
index 0000000..ebb39a7
--- /dev/null
+++ b/BookAPI/Model/Book.cs
@@ -0,0 +1,19 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace BookAPI.Model
+{
+ public class Book
+ {
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+ public string Title { get; set; }
+ public DateTime PublicationDate { get; set; }
+ [ForeignKey("Author")]
+ public int AuthorId { get; set; }
+ //[ForeignKey("Publisher")]
+ //public int PublisherId { get; set; }
+ public Author Author { get; set; }
+ //public Publisher Publisher { get; set; }
+ }
+
+}
diff --git a/BookAPI/Model/Publisher.cs b/BookAPI/Model/Publisher.cs
new file mode 100644
index 0000000..cb868c8
--- /dev/null
+++ b/BookAPI/Model/Publisher.cs
@@ -0,0 +1,15 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace BookAPI.Model
+{
+ public class Publisher
+ {
+ [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public string Address { get; set; }
+ public ICollection Authors { get; set; }
+ public ICollection Books { get; set; }
+ }
+
+}
diff --git a/BookAPI/Program.cs b/BookAPI/Program.cs
new file mode 100644
index 0000000..0a83e09
--- /dev/null
+++ b/BookAPI/Program.cs
@@ -0,0 +1,38 @@
+using BookAPI.Data;
+using BookAPI.Model;
+using BookAPI.Service.Implementation;
+using BookAPI.Service.Interface;
+using Microsoft.EntityFrameworkCore;
+
+var builder = WebApplication.CreateBuilder(args);
+
+// Add services to the container.
+
+builder.Services.AddControllers();
+// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());
+builder.Services.AddDbContext(options =>
+{ options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")); });
+builder.Services.AddScoped();
+builder.Services.AddScoped,BookRepository>();
+builder.Services.AddScoped();
+
+builder.Services.AddSwaggerGen();
+
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+if (app.Environment.IsDevelopment())
+{
+ app.UseSwagger();
+ app.UseSwaggerUI();
+}
+
+app.UseHttpsRedirection();
+
+app.UseAuthorization();
+
+app.MapControllers();
+
+app.Run();
diff --git a/BookAPI/Properties/launchSettings.json b/BookAPI/Properties/launchSettings.json
new file mode 100644
index 0000000..6bc97e5
--- /dev/null
+++ b/BookAPI/Properties/launchSettings.json
@@ -0,0 +1,31 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:48188",
+ "sslPort": 44394
+ }
+ },
+ "profiles": {
+ "BookAPI": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "applicationUrl": "https://localhost:7237;http://localhost:5023",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Express": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/BookAPI/README.md b/BookAPI/README.md
new file mode 100644
index 0000000..406ef50
--- /dev/null
+++ b/BookAPI/README.md
@@ -0,0 +1 @@
+This a simple BookAPI that has CRUD operations for three models which include Author,Book and Publisher
diff --git a/BookAPI/Service/Implementation/AuthorRepository.cs b/BookAPI/Service/Implementation/AuthorRepository.cs
new file mode 100644
index 0000000..18f3f04
--- /dev/null
+++ b/BookAPI/Service/Implementation/AuthorRepository.cs
@@ -0,0 +1,63 @@
+using AutoMapper;
+using BookAPI.Data;
+using BookAPI.Dto;
+using BookAPI.Model;
+using BookAPI.Service.Interface;
+using Microsoft.EntityFrameworkCore;
+
+namespace BookAPI.Service.Implementation
+{
+ public class AuthorRepository : IAuthorRepository
+ {
+ private readonly ApplicationDbContext _dbContext;
+
+ public AuthorRepository(ApplicationDbContext dbContext)
+ {
+ _dbContext = dbContext;
+
+ }
+
+ public async Task> GetAllAsync()
+ {
+ return await _dbContext.Authors.ToListAsync();
+
+ }
+
+ public async Task GetByIdAsync(int id)
+ {
+ var author = await _dbContext.Authors.FindAsync(id);
+ return author;
+ }
+
+ public async Task AddAsync(Author entity)
+ {
+
+ await _dbContext.Authors.AddAsync(entity);
+ await _dbContext.SaveChangesAsync();
+ }
+
+
+ public async Task> GetBooksAttachedToAuthor(int authorId)
+ {
+ var books = await _dbContext.Books.Where(b => b.AuthorId == authorId).ToListAsync();
+
+ return books;
+ }
+
+ //Task> IRepository.GetAllAsync()
+ //{
+ // throw new NotImplementedException();
+ //}
+
+ //Task IRepository.GetByIdAsync(int id)
+ //{
+ // throw new NotImplementedException();
+ //}
+
+ //Task IRepository.AddAsync(Author entity)
+ //{
+ // throw new NotImplementedException();
+ //}
+ }
+
+}
diff --git a/BookAPI/Service/Implementation/BookRepository.cs b/BookAPI/Service/Implementation/BookRepository.cs
new file mode 100644
index 0000000..fbab0a1
--- /dev/null
+++ b/BookAPI/Service/Implementation/BookRepository.cs
@@ -0,0 +1,39 @@
+using AutoMapper;
+using BookAPI.Data;
+using BookAPI.Dto;
+using BookAPI.Model;
+using BookAPI.Service.Interface;
+using Microsoft.EntityFrameworkCore;
+
+namespace BookAPI.Service.Implementation
+{
+ public class BookRepository : IRepository
+ {
+ private readonly ApplicationDbContext _dbContext;
+
+
+ public BookRepository(ApplicationDbContext dbContext)
+ {
+ _dbContext = dbContext;
+ }
+
+ public async Task> GetAllAsync()
+ {
+ return await _dbContext.Books.ToListAsync();
+ }
+
+ public async Task GetByIdAsync(int id)
+ {
+ var book = await _dbContext.Books.FindAsync(id);
+ return book;
+
+ }
+
+ public async Task AddAsync(Book entity)
+ {
+ await _dbContext.AddAsync(entity);
+ await _dbContext.SaveChangesAsync();
+ }
+ }
+
+}
diff --git a/BookAPI/Service/Implementation/PublisherRepository.cs b/BookAPI/Service/Implementation/PublisherRepository.cs
new file mode 100644
index 0000000..e34610e
--- /dev/null
+++ b/BookAPI/Service/Implementation/PublisherRepository.cs
@@ -0,0 +1,45 @@
+using AutoMapper;
+using BookAPI.Data;
+using BookAPI.Dto;
+using BookAPI.Model;
+using BookAPI.Service.Interface;
+using Microsoft.EntityFrameworkCore;
+
+namespace BookAPI.Service.Implementation
+{
+ public class PublisherRepository : IPublisherRepository
+ {
+ private readonly ApplicationDbContext _dbContext;
+ private readonly IMapper _mapper;
+
+ public PublisherRepository(ApplicationDbContext dbContext)
+ {
+ _dbContext = dbContext;
+
+ }
+
+ public async Task> GetAllAsync()
+ {
+ return await _dbContext.Publishers.ToListAsync();
+
+ }
+
+ public async Task GetByIdAsync(int id)
+ {
+ var publisher = await _dbContext.Publishers.FindAsync(id);
+ return publisher;
+
+ }
+
+ public async Task AddAsync(Publisher entity)
+ {
+ await _dbContext.Publishers.AddAsync(entity);
+ await _dbContext.SaveChangesAsync();
+ }
+
+ public async Task> GetAuthorsAttachedToPublisher(int publisherId)
+ {
+ return _dbContext.Authors.Where(a => a.PublisherId == publisherId).ToList();
+ }
+ }
+}
diff --git a/BookAPI/Service/Interface/IAuthorRepository.cs b/BookAPI/Service/Interface/IAuthorRepository.cs
new file mode 100644
index 0000000..6d18f15
--- /dev/null
+++ b/BookAPI/Service/Interface/IAuthorRepository.cs
@@ -0,0 +1,9 @@
+using BookAPI.Model;
+
+namespace BookAPI.Service.Interface
+{
+ public interface IAuthorRepository : IRepository
+ {
+ Task> GetBooksAttachedToAuthor(int authorId);
+ }
+}
diff --git a/BookAPI/Service/Interface/IPublisherRepository.cs b/BookAPI/Service/Interface/IPublisherRepository.cs
new file mode 100644
index 0000000..04bbf5c
--- /dev/null
+++ b/BookAPI/Service/Interface/IPublisherRepository.cs
@@ -0,0 +1,13 @@
+using BookAPI.Dto;
+using BookAPI.Model;
+
+namespace BookAPI.Service.Interface
+{
+ public interface IPublisherRepository : IRepository
+ {
+ // other methods in the interface...
+
+ Task> GetAuthorsAttachedToPublisher(int publisherId);
+ }
+
+}
diff --git a/BookAPI/Service/Interface/IRepositoryInterface.cs b/BookAPI/Service/Interface/IRepositoryInterface.cs
new file mode 100644
index 0000000..cf50f56
--- /dev/null
+++ b/BookAPI/Service/Interface/IRepositoryInterface.cs
@@ -0,0 +1,10 @@
+namespace BookAPI.Service.Interface
+{
+ public interface IRepository where T : class
+ {
+ Task> GetAllAsync();
+ Task GetByIdAsync(int id);
+ Task AddAsync(T entity);
+ }
+
+}
diff --git a/BookAPI/appsettings.Development.json b/BookAPI/appsettings.Development.json
new file mode 100644
index 0000000..0c208ae
--- /dev/null
+++ b/BookAPI/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ }
+}
diff --git a/BookAPI/appsettings.json b/BookAPI/appsettings.json
new file mode 100644
index 0000000..167083b
--- /dev/null
+++ b/BookAPI/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "ConnectionStrings": { "DefaultConnection": "server=LAPTOP-C6680A7T\\SQLEXPRESS;database=BookAPI;Integrated Security=true;" },
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.AspNetCore": "Warning"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/Console banking/FraudulentBank.Customer/Customer.cs b/Console banking/FraudulentBank.Customer/Customer.cs
new file mode 100644
index 0000000..3bfb1bd
--- /dev/null
+++ b/Console banking/FraudulentBank.Customer/Customer.cs
@@ -0,0 +1,496 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Numerics;
+using System.Reflection;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using System.Transactions;
+using static System.Net.Mime.MediaTypeNames;
+
+namespace FraudulentBank.Customer
+{
+
+
+ public class Transaction
+ {
+ public DateTime Date { get; set; }
+ public string TransactionType { get; set; }
+ public decimal Amount { get; set; }
+ public string AccountNumber { get; set; }
+ public Transaction(string accountNumber, string transactionType, decimal amount, DateTime date)
+ {
+ AccountNumber = accountNumber;
+ TransactionType = transactionType;
+ Amount = amount;
+ Date = date;
+ }
+ }
+
+
+ public class Customer
+ {
+ public string Name { get; set; }
+ public string Email { get; set; }
+ public string AccountNumber { get; set; }
+ public decimal Balance { get; set; }
+ public string Password { get; set; }
+ public List? Transactions { get; set; }
+
+ public Customer(string name, string accountNumber, string hashedPassword, string email, decimal balance)
+ {
+ Name = name;
+ Email = email;
+ Password = hashedPassword;
+ AccountNumber = accountNumber;
+ Balance = balance;
+ Transactions = new List();
+ }
+
+
+ public static void SignUp()
+ {
+ Console.Write("Kindly Enter Your Name: ");
+ string name = Console.ReadLine();
+
+
+ Console.Write("Kindly Enter Your Email: ");
+ string email = Console.ReadLine();
+
+ Console.Write("Kindly Enter Your Password: ");
+ string password = "";
+ while (true)
+ {
+ ConsoleKeyInfo key = Console.ReadKey(true);
+ if (key.Key == ConsoleKey.Enter)
+ {
+ break;
+ }
+ else if (key.Key == ConsoleKey.Backspace && password.Length > 0)
+ {
+ password = password.Remove(password.Length - 1);
+ Console.Write("\b \b");
+ }
+ else if (key.KeyChar != '\u0000' && !char.IsControl(key.KeyChar))
+ {
+ password += key.KeyChar;
+ Console.Write("*");
+ }
+ }
+
+ string accountNumber = GenerateAccountNumber();
+
+ decimal balance = 0;
+
+ List transactions = new List();
+
+ string hashedPassword = HashPassword(password);
+
+ var customer = new Customer(name, hashedPassword, email, accountNumber, balance);
+
+
+ string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{customer.AccountNumber}.txt";
+ using (StreamWriter writer = new StreamWriter(fileName))
+ {
+ writer.WriteLine($"Name: {customer.Name}");
+ writer.WriteLine($"Email: {customer.Email}");
+ writer.WriteLine($"Account Number: {customer.AccountNumber}");
+ writer.WriteLine($"Password: {customer.Password}");
+ writer.WriteLine($"Balance: {customer.Balance}");
+ writer.WriteLine("Transaction History:");
+ }
+ Console.WriteLine($"Congratulations {name}! Your account has been created with account number {accountNumber}.");
+ Console.WriteLine("Press 1 to login, or any other key to exit.");
+ string choice = Console.ReadLine();
+
+ if (choice == "1")
+ {
+ Login();
+ }
+ else
+ {
+ Console.WriteLine("Goodbye! Thanks for using our banking application.");
+ Environment.Exit(0);
+
+ }
+ }
+
+
+
+ public static void SaveCustomersToFile(List Customers)
+ {
+ string fileName = "Customers.txt";
+ string filePath = @"C:\Users\Oluwafemi.Dally\Documents\" + fileName;
+
+ using (StreamWriter writer = new StreamWriter(filePath))
+ {
+ foreach (Customer customer in Customers)
+ {
+ writer.WriteLine($"{customer.Name},{customer.AccountNumber},{customer.Password},{customer.Email},{customer.Balance}");
+ }
+ }
+ }
+
+
+ static string GenerateAccountNumber()
+ {
+ List Customers = new List();
+ Random random = new Random();
+ string accountNumber;
+ do
+ {
+ accountNumber = "20" + random.Next(10000000, 100000000).ToString();
+ } while (Customers.Any(c => c.AccountNumber == accountNumber));
+
+ return accountNumber;
+ }
+
+ static string HashPassword(string password)
+ {
+ using (var sha256 = SHA256.Create())
+ {
+ var hashedBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
+ var hash = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
+ return hash;
+ }
+ }
+
+ public static void Login()
+ {
+ Console.WriteLine("Enter your account number: ");
+ string accountNumber = Console.ReadLine();
+ Console.WriteLine("Enter your password: ");
+ string password = "";
+ while (true)
+ {
+ ConsoleKeyInfo key = Console.ReadKey(true);
+ if (key.Key == ConsoleKey.Enter)
+ {
+ break;
+ }
+ else if (key.Key == ConsoleKey.Backspace && password.Length > 0)
+ {
+ password = password.Remove(password.Length - 1);
+ Console.Write("\b \b");
+ }
+ else if (key.KeyChar != '\u0000' && !char.IsControl(key.KeyChar))
+ {
+ password += key.KeyChar;
+ Console.Write("*");
+ }
+ }
+
+ string hashedPassword = Customer.HashPassword(password);
+
+ // Load customer data from file with account number as file name
+ string fileName = $"{accountNumber}.txt";
+ Customer c = Customer.LoadCustomerFromFile(accountNumber);
+
+ if (c != null && c.Password == hashedPassword)
+ {
+ Console.WriteLine("Login Successful.");
+ bool isLoggedIn = true;
+
+ while (isLoggedIn)
+ {
+ Console.WriteLine("\nPlease select an option:");
+ Console.WriteLine("1. Deposit");
+ Console.WriteLine("2. Withdraw");
+ Console.WriteLine("3. View Balance");
+ Console.WriteLine("4. Transaction History");
+ Console.WriteLine("5. Exit");
+
+ string choice = Console.ReadLine();
+
+ switch (choice)
+ {
+ case "1":
+ Deposit(accountNumber);
+ break;
+
+ case "2":
+ Withdraw(accountNumber);
+ break;
+
+ case "3":
+ ViewBalance();
+ break;
+
+ case "4":
+ DisplayTransactionHistory();
+ break;
+
+ case "5":
+ isLoggedIn = false;
+ Console.WriteLine("Goodbye! Thanks for using our banking application.");
+ Environment.Exit(5);
+ break;
+
+ default:
+ Console.WriteLine("Invalid option, please try again.");
+ break;
+ }
+
+ }
+ }
+ else
+ {
+ Console.WriteLine("Invalid account number or password.");
+
+ }
+ }
+
+ public static bool AuthenticateCustomer(string accountNumber, string hashedPassword)
+ {
+ var Customers = new List();
+ foreach (Customer customer in Customers)
+ {
+ if (customer.AccountNumber == accountNumber && customer.Password == hashedPassword)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ //public static List LoadCustomersFromFile()
+ //{
+ // List customers = new List();
+
+ // try
+ // {
+ // string fileName = "Customers.txt";
+ // string filePath = @"C:\Users\Oluwafemi.Dally\Documents\" + fileName;
+ // if (File.Exists(filePath))
+ // {
+ // string[] lines = File.ReadAllLines(filePath);
+ // foreach (string line in lines)
+ // {
+ // string[] fields = line.Split(',');
+ // string name = fields[0];
+ // string hashedPassword = fields[1];
+ // string email = fields[2];
+ // string accountNumber = fields[3];
+ // decimal balance = decimal.Parse(fields[4]);
+
+ // Customer customer = new Customer(name, hashedPassword, email, accountNumber, balance);
+ // customers.Add(customer);
+ // }
+ // }
+ // }
+ // catch (Exception ex)
+ // {
+ // Console.WriteLine($"An error occurred while loading customers from file: {ex.Message}");
+ // }
+
+ // return customers;
+ //}
+
+ public static Customer LoadCustomerFromFile(string accountNumber)
+ {
+ string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt";
+
+ if (!File.Exists(fileName))
+ {
+ throw new FileNotFoundException($"File not found: {fileName}");
+ }
+
+ string[] lines = File.ReadAllLines(fileName);
+
+ if (lines.Length < 5)
+ {
+ throw new FormatException("File has incorrect format.");
+ }
+
+ string name = lines[0].Substring(6);
+ string loadedAccountNumber = lines[2].Substring(16);
+ string hashedPassword = lines[3].Substring(10);
+ string email = lines[1].Substring(7);
+ decimal balance = decimal.Parse(lines[4].Substring(9));
+
+ Customer customer = new Customer(name, accountNumber, hashedPassword, email, balance);
+
+ return customer;
+ }
+
+
+
+
+
+
+ public static void Deposit(string accountNumber)
+ {
+ Console.Write("Enter the deposit amount: ");
+ decimal amount = decimal.Parse(Console.ReadLine());
+
+
+ string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt";
+ Customer c = Customer.LoadCustomerFromFile(accountNumber);
+
+ if (c.AccountNumber != accountNumber)
+ {
+ Console.WriteLine("Invalid account number.");
+ return;
+ }
+
+ // Create a new transaction object and add it to the customer's transactions list
+ var transaction = new Transaction(accountNumber, "Deposit", amount, DateTime.Now);
+
+
+ // Update the customer's balance
+ c.Balance += amount;
+
+
+ // Append transaction to transaction history file
+ string transactionFileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}_transaction.txt";
+ using (StreamWriter writer = File.AppendText(transactionFileName))
+ {
+ writer.WriteLine($"{transaction.AccountNumber}|{transaction.TransactionType}|{transaction.Amount}|{transaction.Date}");
+ }
+
+ Console.WriteLine($"Transaction successful. Your new balance is {c.Balance:C}");
+ }
+
+
+
+
+ public static void SaveTransactionToFile(string accountNumber, Transaction transaction)
+ {
+ string fileName = "Transaction.txt";
+ string filePath = @"C:\Users\Oluwafemi.Dally\Documents\" + fileName;
+
+ // Write the transaction data to the file
+ using (StreamWriter writer = File.AppendText(filePath))
+ {
+ string transactionData = $"{accountNumber},{transaction.TransactionType},{transaction.Amount},{transaction.Date}";
+ writer.WriteLine(transactionData);
+ }
+ }
+
+ public static List LoadTransactionHistoryFromFile(string accountNumber)
+ {
+ string fileName = $@"C:\Users\Oluwafemi.Dally\Documents\{accountNumber}_transaction.txt";
+
+ if (!File.Exists(fileName))
+ {
+ throw new FileNotFoundException($"File not found: {fileName}");
+ }
+
+ List transactions = new List();
+
+ using (StreamReader reader = new StreamReader(fileName))
+ {
+ string line;
+ while ((line = reader.ReadLine()) != null)
+ {
+ string[] fields = line.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
+ DateTime date = DateTime.ParseExact(fields[3], "M/d/yyyy h:mm:ss tt", CultureInfo.InvariantCulture);
+ string TransactionType = fields[1];
+ decimal amount = decimal.Parse(fields[2]);
+ Transaction transaction = new Transaction(accountNumber, TransactionType, amount, date);
+ transactions.Add(transaction);
+ }
+ }
+
+ return transactions;
+ }
+
+
+
+
+ public static void Withdraw(string accountNumber)
+ {
+ Console.Write("Enter the withdrawal amount: ");
+ decimal amount = decimal.Parse(Console.ReadLine());
+
+ List Customers = new List();
+
+ string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt";
+ Customer c = Customer.LoadCustomerFromFile(accountNumber);
+
+ if (c.AccountNumber != accountNumber)
+ {
+ Console.WriteLine("Invalid account number.");
+ return;
+ }
+
+ if (amount > c.Balance)
+ {
+ Console.WriteLine("Insufficient funds.");
+ return;
+ }
+
+ var transaction = new Transaction(accountNumber, "Withdrawal", amount, DateTime.Now);
+
+ // Update the customer's balance
+ c.Balance -= amount;
+
+ // Append transaction to transaction history file
+ string transactionFileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}_transaction.txt";
+ using (StreamWriter writer = File.AppendText(transactionFileName))
+ {
+ writer.WriteLine($"{transaction.AccountNumber}|{transaction.TransactionType}|{transaction.Amount}|{transaction.Date}");
+ }
+
+ Console.WriteLine($"Transaction successful. Your new balance is {c.Balance:C}");
+ }
+
+
+ public static void DisplayTransactionHistory()
+ {
+ Console.WriteLine("Enter your account number:");
+ string accountNumber = Console.ReadLine();
+
+ string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt";
+ string transactionFileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}_transaction.txt";
+
+ Customer c = Customer.LoadCustomerFromFile(accountNumber);
+
+ if (c.AccountNumber != accountNumber)
+ {
+ Console.WriteLine("Invalid account number.");
+ return;
+ }
+
+ else
+ {
+ // Display the customer's transaction history
+ Console.WriteLine($"Transaction history for {c.Name} ({c.AccountNumber}):");
+ List transactions = LoadTransactionHistoryFromFile(accountNumber);
+ foreach (Transaction transaction in transactions)
+ {
+ Console.WriteLine($"Date: {transaction.Date}\tType: {transaction.TransactionType}\tAmount: {transaction.Amount:C}");
+ }
+ }
+ }
+
+
+ public static void ViewBalance()
+ {
+ Console.Write("Account number: ");
+ string accountNumber = Console.ReadLine();
+
+ string fileName = @"C:\Users\Oluwafemi.Dally\Documents\" + $"{accountNumber}.txt";
+ Customer c = Customer.LoadCustomerFromFile(accountNumber);
+
+ if (c.AccountNumber != accountNumber)
+ {
+ Console.WriteLine("Invalid account number.");
+ return;
+ }
+ else
+ {
+ Console.WriteLine($"Balance: NGN{c.Balance:C}");
+ }
+
+
+ }
+
+ }
+}
+
diff --git a/Console banking/FraudulentBank.Customer/FraudulentBank.Customer.csproj b/Console banking/FraudulentBank.Customer/FraudulentBank.Customer.csproj
new file mode 100644
index 0000000..27ac386
--- /dev/null
+++ b/Console banking/FraudulentBank.Customer/FraudulentBank.Customer.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
diff --git a/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.csproj b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.csproj
new file mode 100644
index 0000000..d90fddc
--- /dev/null
+++ b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.csproj
@@ -0,0 +1,13 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
diff --git a/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.sln b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.sln
new file mode 100644
index 0000000..5751492
--- /dev/null
+++ b/Console banking/FraudulentBank.Presentation/FraudulentBank.Presentation.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33103.184
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FraudulentBank.Presentation", "FraudulentBank.Presentation.csproj", "{EF171E09-77E8-497C-941B-7034CFEB0726}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FraudulentBank.Customer", "..\FraudulentBank.Customer\FraudulentBank.Customer.csproj", "{2F204812-D56D-4E5B-8DE2-E43E643DEEE6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EF171E09-77E8-497C-941B-7034CFEB0726}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EF171E09-77E8-497C-941B-7034CFEB0726}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EF171E09-77E8-497C-941B-7034CFEB0726}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EF171E09-77E8-497C-941B-7034CFEB0726}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2F204812-D56D-4E5B-8DE2-E43E643DEEE6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {012BDA32-9D27-4202-BAC0-7B347D081F25}
+ EndGlobalSection
+EndGlobal
diff --git a/Console banking/FraudulentBank.Presentation/Program.cs b/Console banking/FraudulentBank.Presentation/Program.cs
new file mode 100644
index 0000000..7649e52
--- /dev/null
+++ b/Console banking/FraudulentBank.Presentation/Program.cs
@@ -0,0 +1,39 @@
+using FraudulentBank.Customer;
+using System.Transactions;
+using System.Xml.Linq;
+
+//static void Main(string[] args)
+{
+ // while (true)
+ {
+ Console.WriteLine("**********WELCOME TO FRAUDULENT BANK*********");
+ Console.WriteLine("1. Sign up");
+ Console.WriteLine("2. Log in");
+ Console.WriteLine("3. Exit");
+ string choice = Console.ReadLine();
+
+
+ switch (choice)
+ {
+ case "1":
+ Customer.SignUp();
+ break;
+ case "2":
+ Customer.Login();
+ break;
+ case "3":
+ Environment.Exit(0);
+ break;
+ default:
+ Console.WriteLine("Invalid choice. Please try again.");
+ break;
+ }
+ }
+}
+
+
+
+
+
+
+