diff --git a/DesignPattnersImplementation.sln b/DesignPattnersImplementation.sln index 3e80785..1454575 100644 --- a/DesignPattnersImplementation.sln +++ b/DesignPattnersImplementation.sln @@ -55,8 +55,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Visitor", "src\Visitor\Visi EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Interpreter", "src\Interpreter\Interpreter.csproj", "{AD8CE3D6-BA70-4D5D-82BB-B81D16D47586}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitOfWork", "src\UnitOfWork\UnitOfWork.csproj", "{33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Repository", "src\Repository\Repository.csproj", "{88674B88-3569-4F93-9C73-FF52559A47B1}" EndProject Global @@ -357,18 +355,6 @@ Global {AD8CE3D6-BA70-4D5D-82BB-B81D16D47586}.Release|x64.Build.0 = Release|Any CPU {AD8CE3D6-BA70-4D5D-82BB-B81D16D47586}.Release|x86.ActiveCfg = Release|Any CPU {AD8CE3D6-BA70-4D5D-82BB-B81D16D47586}.Release|x86.Build.0 = Release|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Debug|Any CPU.Build.0 = Debug|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Debug|x64.ActiveCfg = Debug|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Debug|x64.Build.0 = Debug|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Debug|x86.ActiveCfg = Debug|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Debug|x86.Build.0 = Debug|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Release|Any CPU.ActiveCfg = Release|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Release|Any CPU.Build.0 = Release|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Release|x64.ActiveCfg = Release|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Release|x64.Build.0 = Release|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Release|x86.ActiveCfg = Release|Any CPU - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846}.Release|x86.Build.0 = Release|Any CPU {88674B88-3569-4F93-9C73-FF52559A47B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {88674B88-3569-4F93-9C73-FF52559A47B1}.Debug|Any CPU.Build.0 = Debug|Any CPU {88674B88-3569-4F93-9C73-FF52559A47B1}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -411,7 +397,6 @@ Global {9C5CC585-85F4-4032-B8E2-03EBD02EFD1E} = {FBFC9E17-B858-4F85-A5EF-C2AE3C56544E} {BEB1DEF9-C0A7-4A24-8D72-697F845D0421} = {FBFC9E17-B858-4F85-A5EF-C2AE3C56544E} {AD8CE3D6-BA70-4D5D-82BB-B81D16D47586} = {FBFC9E17-B858-4F85-A5EF-C2AE3C56544E} - {33EBE2B3-4D5C-4D2B-A6C4-BDCC47C41846} = {FBFC9E17-B858-4F85-A5EF-C2AE3C56544E} {88674B88-3569-4F93-9C73-FF52559A47B1} = {FBFC9E17-B858-4F85-A5EF-C2AE3C56544E} EndGlobalSection EndGlobal diff --git a/README.md b/README.md index c6a2c4b..5183069 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,6 @@ Crie esse repositório para ir explorar todos eles - Iterator :white_check_mark: - Visitor :white_check_mark: - Interpreter :white_check_mark: -- **Enterprise (Infrastructure)** +- **Enterprise (Compartilha mesma pasta Repository)** - Repository :white_check_mark: - Unit of Work :white_check_mark: diff --git a/src/Interpreter/Implementation.cs b/src/Interpreter/Implementation.cs new file mode 100644 index 0000000..97f6e2a --- /dev/null +++ b/src/Interpreter/Implementation.cs @@ -0,0 +1,166 @@ +namespace Interpreter +{ + /// + /// Context + /// + public class RomanContext + { + public int Input { get; set; } + public string Output { get; set; } = string.Empty; + + public RomanContext(int input) + { + Input = input; + } + } + + /// + /// Abstraction expression + /// + public abstract class RomanExpression + { + public abstract void Interpret(RomanContext context); + } + + //9 = IX + //8 = VIII + //7 = VII + //6 = VI + //5 = V + //4 = IV + //3 = III + //2 = II + //1 = I + + //simplified - each combination is reachable with subscription and these 4: + //9 = IX + //5 = V + //4 = IV + //1 = I + + + /// + /// Terminal Expression + /// + public class RomanOneExpression : RomanExpression + { + public override void Interpret(RomanContext context) + { + while((context.Input - 9) >= 0) + { + context.Output += "IX"; + context.Input -= 9; + } + + while((context.Input - 5) >= 0) + { + context.Output += "V"; + context.Input -= 5; + } + + while((context.Input - 4) >= 0) + { + context.Output += "IV"; + context.Input -= 4; + } + + while((context.Input - 1) >= 0) + { + context.Output += "I"; + context.Input -= 1; + } + } + } + + //90 = XC + //80 = LIII + //70 = LII + //60 = LX + //50 = L + //40 = XL + //30 = XXX + //20 = XX + //10 = X + + //simplified - each combination is reachable with subscription and these 4: + //90 = XC + //50 = L + //40 = XL + //10 = X + + public class RomanTenExpression : RomanExpression + { + public override void Interpret(RomanContext context) + { + while ((context.Input - 90) >= 0) + { + context.Output += "XC"; + context.Input -= 90; + } + + while ((context.Input - 50) >= 0) + { + context.Output += "L"; + context.Input -= 50; + } + + while ((context.Input - 40) >= 0) + { + context.Output += "XL"; + context.Input -= 40; + } + + while ((context.Input - 10) >= 0) + { + context.Output += "X"; + context.Input -= 10; + } + } + } + + //900 = CM + //800 = DCCC + //700 = DCC + //600 = DC + //500 = D + //400 = CD + //300 = CCC + //200 = CC + //100 = C + + //simplified - each combination is reachable with subscription and these 4: + //900 = CM + //500 = D + //400 = CD + //100 = C + + public class RomanHundreExpression : RomanExpression + { + public override void Interpret(RomanContext context) + { + while ((context.Input - 900) >= 0) + { + context.Output += "CM"; + context.Input -= 900; + } + + while ((context.Input - 500) >= 0) + { + context.Output += "D"; + context.Input -= 500; + } + + while ((context.Input - 400) >= 0) + { + context.Output += "CD"; + context.Input -= 400; + } + + while ((context.Input - 100) >= 0) + { + context.Output += "C"; + context.Input -= 100; + } + } + } +} \ No newline at end of file diff --git a/src/Interpreter/Program.cs b/src/Interpreter/Program.cs index d7abbbe..f3c526b 100644 --- a/src/Interpreter/Program.cs +++ b/src/Interpreter/Program.cs @@ -1,11 +1,41 @@ using System; +using System.Collections.Generic; namespace Interpreter; -class Program +static class Program { static void Main(string[] args) { - Console.WriteLine("Hello, World!"); + var expressions = new List + { + new RomanHundreExpression(), + new RomanTenExpression(), + new RomanOneExpression() + }; + + var context = new RomanContext(5); + foreach (var expression in expressions) + { + expression.Interpret(context); + } + + Console.WriteLine($"Translating Arabic numerals to Roman numerals: 5 {context.Output}"); + + context = new RomanContext(81); + foreach (var expression in expressions) + { + expression.Interpret(context); + } + + Console.WriteLine($"Translating Arabic numerals to Roman numerals: 81 {context.Output}"); + + context = new RomanContext(733); + foreach (var expression in expressions) + { + expression.Interpret(context); + } + + Console.WriteLine($"Translating Arabic numerals to Roman numerals: 733 {context.Output}"); } } diff --git a/src/Repository/Data/AppDbContext.cs b/src/Repository/Data/AppDbContext.cs new file mode 100644 index 0000000..b2c8a2e --- /dev/null +++ b/src/Repository/Data/AppDbContext.cs @@ -0,0 +1,40 @@ +using Microsoft.EntityFrameworkCore; +using Repository.Entities; + +namespace Repository.Data +{ + public class AppDbContext : DbContext + { + public DbSet Products => Set(); + public DbSet Categories => Set(); + + public AppDbContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.HasKey(x => x.Id); + + entity.Property(x => x.Name) + .HasMaxLength(150) + .IsRequired(); + + entity.Property(x => x.Price) + .HasPrecision(10, 2); + }); + + modelBuilder.Entity(entity => + { + entity.HasKey(x => x.Id); + + entity.Property(x => x.Name) + .HasMaxLength(150) + .IsRequired(); + }); + } + } +} \ No newline at end of file diff --git a/src/Repository/Entities/Category.cs b/src/Repository/Entities/Category.cs new file mode 100644 index 0000000..0db80a3 --- /dev/null +++ b/src/Repository/Entities/Category.cs @@ -0,0 +1,13 @@ +using System; + +namespace Repository.Entities +{ + public class Category + { + public Guid Id { get; set; } + + public string Name { get; set; } = string.Empty; + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + } +} \ No newline at end of file diff --git a/src/Repository/Entities/Product.cs b/src/Repository/Entities/Product.cs new file mode 100644 index 0000000..53eac51 --- /dev/null +++ b/src/Repository/Entities/Product.cs @@ -0,0 +1,15 @@ +using System; + +namespace Repository.Entities +{ + public class Product + { + public Guid Id { get; set; } + + public string Name { get; set; } = string.Empty; + + public decimal Price { get; set; } + + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; + } +} \ No newline at end of file diff --git a/src/Repository/Program.cs b/src/Repository/Program.cs index 13125e2..9b9de40 100644 --- a/src/Repository/Program.cs +++ b/src/Repository/Program.cs @@ -1,11 +1,87 @@ using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Repository.Data; +using Repository.Entities; +using Repository.UnitOfWork; namespace Repository; -class Program +static class Program { - static void Main(string[] args) + static async Task Main(string[] args) { - Console.WriteLine("Hello, World!"); + var conn = "Host=localhost;Port=5432;Database=repositorydb;Username=postgres;Password=postgres"; + + try + { + var builder = Host.CreateApplicationBuilder(args); + + builder.Services.AddDbContext(options => + { + options.UseNpgsql(conn); + }); + + //builder.Services.AddScoped(typeof(IRepository<>), typeof(Repository<>)); + //builder.Services.AddScoped(); + builder.Services.AddScoped(); + + var app = builder.Build(); + + using (var scope = app.Services.CreateScope()) + { + var context = scope.ServiceProvider.GetRequiredService(); + var unitOfWork = scope.ServiceProvider.GetRequiredService(); + + await context.Database.EnsureCreatedAsync(); + await context.Database.OpenConnectionAsync(); + + //var genericRepository = scope.ServiceProvider.GetRequiredService>(); + //var productRepository = scope.ServiceProvider.GetRequiredService(); + + var category = new Category + { + Id = Guid.NewGuid(), + Name = "Hardware" + }; + + await unitOfWork.Categories.AddAsync(category); + + var product = new Product + { + Id = Guid.NewGuid(), + Name = "Playstation 5 Pro", + Price = 1000 + }; + + await unitOfWork.Products.AddAsync(product); + await unitOfWork.CommitAsync(); + + //genericRepository.AddAsync(product).GetAwaiter(); + //genericRepository.SaveChangesAsync().GetAwaiter(); + + Console.WriteLine("Transação concluida"); + + //var products = productRepository.GetProductsMoreExpensiveThan(10).GetAwaiter().GetResult(); + var products = await unitOfWork.ProductRepository.GetProductsMoreExpensiveThan(10); + var categories = await unitOfWork.Categories.GetAllAsync(); + + foreach (var item in products) + { + Console.WriteLine($"product: {item.Name} - {item.Price}"); + } + + foreach (var item in categories) + { + Console.WriteLine($"product: {item.Name}"); + } + } + } + catch (Exception ex) + { + Console.WriteLine("Error {0}", ex.Message); + } } } diff --git a/src/Repository/Repositories/CategoryRepository.cs b/src/Repository/Repositories/CategoryRepository.cs new file mode 100644 index 0000000..4f2dae9 --- /dev/null +++ b/src/Repository/Repositories/CategoryRepository.cs @@ -0,0 +1,21 @@ +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Repository.Data; +using Repository.Entities; +using Repository.Repositories.Interaces; + +namespace Repository.Repositories +{ + public class CategoryRepository: Repository, ICategoryRepository + { + public CategoryRepository(AppDbContext context): base(context) + { + } + + public async Task GetByNameAsync(string name) + { + return await _dbSet + .FirstOrDefaultAsync(x => x.Name == name); + } + } +} \ No newline at end of file diff --git a/src/Repository/Repositories/Interfaces/ICategoryRepository.cs b/src/Repository/Repositories/Interfaces/ICategoryRepository.cs new file mode 100644 index 0000000..7ca3e17 --- /dev/null +++ b/src/Repository/Repositories/Interfaces/ICategoryRepository.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; +using Repository.Entities; + +namespace Repository.Repositories.Interaces +{ + public interface ICategoryRepository + { + Task GetByNameAsync(string name); + } +} \ No newline at end of file diff --git a/src/Repository/Repositories/Interfaces/IProductRepository.cs b/src/Repository/Repositories/Interfaces/IProductRepository.cs new file mode 100644 index 0000000..364b1c6 --- /dev/null +++ b/src/Repository/Repositories/Interfaces/IProductRepository.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Repository.Entities; + +namespace Repository.Repositories.Interaces +{ + public interface IProductRepository + { + Task> GetProductsMoreExpensiveThan(decimal price); + + Task GetByNameAsync(string name); + } +} \ No newline at end of file diff --git a/src/Repository/Repositories/Interfaces/IRepository.cs b/src/Repository/Repositories/Interfaces/IRepository.cs new file mode 100644 index 0000000..c1cd272 --- /dev/null +++ b/src/Repository/Repositories/Interfaces/IRepository.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Repository.Repositories.Interaces +{ + public interface IRepository where T : class + { + Task GetByIdAsync(Guid id); + + Task> GetAllAsync(); + + Task AddAsync(T entity); + + void Update(T entity); + + void Remove(T entity); + + Task SaveChangesAsync(); + } +} \ No newline at end of file diff --git a/src/Repository/Repositories/ProductRepository.cs b/src/Repository/Repositories/ProductRepository.cs new file mode 100644 index 0000000..8d3865a --- /dev/null +++ b/src/Repository/Repositories/ProductRepository.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Repository.Data; +using Repository.Entities; +using Repository.Repositories.Interaces; + +namespace Repository.Repositories +{ + public class ProductRepository: Repository, IProductRepository + { + public ProductRepository(AppDbContext context) + : base(context) + { + } + + public async Task> GetProductsMoreExpensiveThan(decimal price) + { + return await _dbSet + .Where(x => x.Price > price) + .ToListAsync(); + } + + public async Task GetByNameAsync(string name) + { + return await _dbSet + .FirstOrDefaultAsync(x => x.Name == name); + } + } +} \ No newline at end of file diff --git a/src/Repository/Repositories/Repository.cs b/src/Repository/Repositories/Repository.cs new file mode 100644 index 0000000..e07b110 --- /dev/null +++ b/src/Repository/Repositories/Repository.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Repository.Data; +using Repository.Repositories.Interaces; + +namespace Repository.Repositories +{ + public class Repository : IRepository where T : class + { + protected readonly AppDbContext _context; + protected readonly DbSet _dbSet; + + public Repository(AppDbContext context) + { + _context = context; + _dbSet = context.Set(); + } + + public async Task GetByIdAsync(Guid id) + { + return await _dbSet.FindAsync(id); + } + + public async Task> GetAllAsync() + { + return await _dbSet.ToListAsync(); + } + + public async Task AddAsync(T entity) + { + await _dbSet.AddAsync(entity); + } + + public void Update(T entity) + { + _dbSet.Update(entity); + } + + public void Remove(T entity) + { + _dbSet.Remove(entity); + } + + public async Task SaveChangesAsync() + { + await _context.SaveChangesAsync(); + } + } +} \ No newline at end of file diff --git a/src/Repository/Repository.csproj b/src/Repository/Repository.csproj index 08ab42e..db4ee99 100644 --- a/src/Repository/Repository.csproj +++ b/src/Repository/Repository.csproj @@ -3,6 +3,18 @@ Exe net10.0 + enable + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + diff --git a/src/Repository/UnitOfWork/IUnitOfWork.cs b/src/Repository/UnitOfWork/IUnitOfWork.cs new file mode 100644 index 0000000..2f12d80 --- /dev/null +++ b/src/Repository/UnitOfWork/IUnitOfWork.cs @@ -0,0 +1,11 @@ +using System.Threading.Tasks; + +namespace Repository.UnitOfWork +{ + public interface IUnitOfWork + { + Task CommitAsync(); + + Task RollbackAsync(); + } +} \ No newline at end of file diff --git a/src/Repository/UnitOfWork/UnitOfWorkBase.cs b/src/Repository/UnitOfWork/UnitOfWorkBase.cs new file mode 100644 index 0000000..64d9fc7 --- /dev/null +++ b/src/Repository/UnitOfWork/UnitOfWorkBase.cs @@ -0,0 +1,64 @@ +using System; +using System.Threading.Tasks; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; + +namespace Repository.UnitOfWork +{ + public abstract class UnitOfWorkBase : IUnitOfWork + { + protected readonly DbContext _context; + + private IDbContextTransaction? _transaction; + + protected UnitOfWorkBase(DbContext context) + { + _context = context; + } + + protected async Task BeginTransactionAsync() + { + if (_transaction is null) + { + _transaction = + await _context.Database.BeginTransactionAsync(); + } + } + + public virtual async Task CommitAsync() + { + try + { + await _context.SaveChangesAsync(); + + if (_transaction is not null) + { + await _transaction.CommitAsync(); + } + } + catch + { + await RollbackAsync(); + throw; + } + } + + public virtual async Task RollbackAsync() + { + if (_transaction is not null) + { + await _transaction.RollbackAsync(); + } + } + + public async ValueTask DisposeAsync() + { + if (_transaction is not null) + { + await _transaction.DisposeAsync(); + } + + await _context.DisposeAsync(); + } + } +} \ No newline at end of file diff --git a/src/Repository/UnitOfWork/UnitOfWorkService.cs b/src/Repository/UnitOfWork/UnitOfWorkService.cs new file mode 100644 index 0000000..7c336cf --- /dev/null +++ b/src/Repository/UnitOfWork/UnitOfWorkService.cs @@ -0,0 +1,31 @@ +using System; +using Microsoft.EntityFrameworkCore; +using Repository.Data; +using Repository.Entities; +using Repository.Repositories; +using Repository.Repositories.Interaces; + +namespace Repository.UnitOfWork +{ + public class UnitOfWorkService : UnitOfWorkBase + { + public IRepository Products { get; } + + public IRepository Categories { get; } + + public IProductRepository ProductRepository { get; } + + public ICategoryRepository CategoryRepository { get; } + + public UnitOfWorkService(AppDbContext context) : base(context) + { + Products = new Repository(context); + + Categories = new Repository(context); + + ProductRepository = new ProductRepository(context); + + CategoryRepository = new CategoryRepository(context); + } + } +} \ No newline at end of file diff --git a/src/Repository/docker-compose.yml b/src/Repository/docker-compose.yml new file mode 100644 index 0000000..1da106c --- /dev/null +++ b/src/Repository/docker-compose.yml @@ -0,0 +1,20 @@ +version: '3.9' + +services: + postgres: + image: postgres:17 + container_name: repository-postgres + + environment: + POSTGRES_DB: repositorydb + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + + ports: + - "5432:5432" + + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + postgres_data: \ No newline at end of file diff --git a/src/UnitOfWork/Program.cs b/src/UnitOfWork/Program.cs deleted file mode 100644 index 42f7565..0000000 --- a/src/UnitOfWork/Program.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace UnitOfWork; - -class Program -{ - static void Main(string[] args) - { - Console.WriteLine("Hello, World!"); - } -} diff --git a/src/UnitOfWork/UnitOfWork.csproj b/src/UnitOfWork/UnitOfWork.csproj deleted file mode 100644 index 08ab42e..0000000 --- a/src/UnitOfWork/UnitOfWork.csproj +++ /dev/null @@ -1,8 +0,0 @@ - - - - Exe - net10.0 - - - diff --git a/src/Visitor/Implementation.cs b/src/Visitor/Implementation.cs new file mode 100644 index 0000000..2b45995 --- /dev/null +++ b/src/Visitor/Implementation.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; + +namespace Visitor +{ + /// + /// Concrete element + /// + public class Customer: IElement + { + public decimal AmountOrdered { get; private set; } + public decimal Discount { get; set; } + public string Name { get; set; } + + public Customer(string name, decimal amountOrdered) + { + Name = name; + AmountOrdered = amountOrdered; + } + + public void Accept(IVisitor visitor) + { + //visitor.VisitCustomer(this); + visitor.Visit(this); + Console.WriteLine($"Visited {nameof(Customer)} {Name}, discount given {Discount}"); + } + } + + /// + /// Concrete element + /// + public class Employee: IElement + { + public int YearsEmployed { get; private set; } + public decimal Discount { get; set; } + public string Name { get; set; } + + public Employee(string name, int yearsEmployed) + { + Name = name; + YearsEmployed = yearsEmployed; + } + + public void Accept(IVisitor visitor) + { + //visitor.VisitEmployee(this); + visitor.Visit(this); + Console.WriteLine($"Visited {nameof(Employee)} {Name}, discount given {Discount}"); + } + } + + /// + /// Visitor + /// + //public interface IVisitor + //{ + // void VisitCustomer(Customer customer); + // void VisitEmployee(Employee employee); + //} + + public interface IVisitor + { + void Visit(IElement element); + } + + /// + /// Element + /// + public interface IElement + { + void Accept(IVisitor visitor); + } + + public class DiscountVisitor : IVisitor + { + public decimal TotalDiscountGiven { get; set; } + + public void Visit(IElement element) + { + if(element is Customer) + { + VisitCustomer((Customer)element); + } + else if (element is Employee) + { + VisitEmployee((Employee)element); + } + } + + private void VisitCustomer(Customer customer) + { + //percentage of total amount + var discount = customer.AmountOrdered / 10; + + //set it on the customer + customer.Discount = discount; + + //add it to the total amount + TotalDiscountGiven += discount; + } + + private void VisitEmployee(Employee employee) + { + //fixed value depending on the amount of years employed + var discount = employee.YearsEmployed < 10 ? 100: 200; + + //set it on the employee + employee.Discount = discount; + + //add it to the total amount + TotalDiscountGiven += discount; + } + + + } + + /// + /// ObjectStructure + /// + public class Container + { + public List Employees { get; set; } = new(); + public List Customers { get; set; } = new(); + + public void Accept(IVisitor visitor) + { + foreach (var employed in Employees) + { + employed.Accept(visitor); + } + + foreach (var customer in Customers) + { + customer.Accept(visitor); + } + } + } +} \ No newline at end of file diff --git a/src/Visitor/Program.cs b/src/Visitor/Program.cs index 379f161..17418ce 100644 --- a/src/Visitor/Program.cs +++ b/src/Visitor/Program.cs @@ -2,10 +2,25 @@ namespace Visitor; -class Program +static class Program { static void Main(string[] args) { - Console.WriteLine("Hello, World!"); + var container = new Container(); + + container.Customers.Add(new Customer("Wodson", 500)); + container.Customers.Add(new Customer("Joao", 600)); + container.Customers.Add(new Customer("Maria", 700)); + + container.Employees.Add(new Employee("Thalia", 20)); + container.Employees.Add(new Employee("Antonio", 5)); + + // create visitor + var discountVisitor = new DiscountVisitor(); + + //pass it through + container.Accept(discountVisitor); + + Console.WriteLine($"Totol discount: {discountVisitor.TotalDiscountGiven}"); } }