diff --git a/Data/Data.csproj b/Data/Data.csproj
new file mode 100644
index 0000000..9c5aa01
--- /dev/null
+++ b/Data/Data.csproj
@@ -0,0 +1,17 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Data/Extentions/ServiceCollectionExtentions.cs b/Data/Extentions/ServiceCollectionExtentions.cs
new file mode 100644
index 0000000..b52c22d
--- /dev/null
+++ b/Data/Extentions/ServiceCollectionExtentions.cs
@@ -0,0 +1,13 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Services.Tickets;
+
+namespace Data.Extentions;
+
+public static class ServiceCollectionExtentions
+{
+ public static void TyAddFakeTicketRepository(this IServiceCollection services)
+ {
+ services.TryAddScoped();
+ }
+}
diff --git a/Data/FakeTicketRepository.cs b/Data/FakeTicketRepository.cs
new file mode 100644
index 0000000..49cee2b
--- /dev/null
+++ b/Data/FakeTicketRepository.cs
@@ -0,0 +1,21 @@
+using Services.Tickets;
+using Services.Tickets.Models;
+
+namespace Data;
+
+internal class FakeTicketRepository : ITicketRepository
+{
+ private readonly List _lotteryTickets = new List();
+ public Task AddNewTicket(LotteryTicket ticket)
+ {
+ var id =(long)Random.Shared.Next(1, 100);
+ ticket.Id = id;
+ _lotteryTickets.Add(ticket);
+ return Task.FromResult(id);
+ }
+
+ public Task> GetAllTickets()
+ {
+ return Task.FromResult(_lotteryTickets);
+ }
+}
diff --git a/Lottery.Tests/GlobalUsings.cs b/Lottery.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..cefced4
--- /dev/null
+++ b/Lottery.Tests/GlobalUsings.cs
@@ -0,0 +1 @@
+global using NUnit.Framework;
\ No newline at end of file
diff --git a/Lottery.Tests/Lottery.Tests.csproj b/Lottery.Tests/Lottery.Tests.csproj
new file mode 100644
index 0000000..66239c2
--- /dev/null
+++ b/Lottery.Tests/Lottery.Tests.csproj
@@ -0,0 +1,24 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Lottery.Tests/NumbersServiceTests.cs b/Lottery.Tests/NumbersServiceTests.cs
new file mode 100644
index 0000000..6781c3e
--- /dev/null
+++ b/Lottery.Tests/NumbersServiceTests.cs
@@ -0,0 +1,36 @@
+using Services.Numbers;
+using Services.Tickets;
+
+namespace Lottery.Tests;
+
+public class NumbersServiceTests
+{
+ [SetUp]
+ public void Setup()
+ {
+ }
+
+ [Test]
+ public void ShouldGenerateUniqNumbers()
+ {
+ var numbersService = new NumbersService();
+ for (int i = 0; i < 1000; i++)
+ {
+ var t = numbersService.GetNumbers(35);
+ CollectionAssert.AllItemsAreUnique(t);
+ }
+ }
+
+ [Test]
+ public void ShouldGenerateRandomNumbers()
+ {
+ var numbersService = new NumbersService();
+
+ List numbers = new List();
+ for (int i = 0; i < 1000; i++)
+ {
+ numbers.Add(numbersService.GetNumbers(6));
+ }
+ CollectionAssert.AllItemsAreUnique(numbers);
+ }
+}
\ No newline at end of file
diff --git a/Lottery.Tickets/Class1.cs b/Lottery.Tickets/Class1.cs
new file mode 100644
index 0000000..741057e
--- /dev/null
+++ b/Lottery.Tickets/Class1.cs
@@ -0,0 +1,6 @@
+namespace Lottery.Tickets;
+
+public class Class1
+{
+
+}
diff --git a/Lottery.Tickets/Lottery.Tickets.csproj b/Lottery.Tickets/Lottery.Tickets.csproj
new file mode 100644
index 0000000..fa71b7a
--- /dev/null
+++ b/Lottery.Tickets/Lottery.Tickets.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/Lottery.sln b/Lottery.sln
new file mode 100644
index 0000000..21b66c7
--- /dev/null
+++ b/Lottery.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.8.34330.188
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Services", "Services\Services.csproj", "{E53B4797-FCFE-418E-B412-E08381A144E3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Data", "Data\Data.csproj", "{1D5D5D3E-2D9A-4AAB-896E-E0957CD75E9A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkerService1", "WorkerService1\WorkerService1.csproj", "{0A24B96A-7B80-486A-9546-B82FC5F99675}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lottery.Tests", "Lottery.Tests\Lottery.Tests.csproj", "{BCBB643F-C468-4EE6-B186-6E2084B644DE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {E53B4797-FCFE-418E-B412-E08381A144E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E53B4797-FCFE-418E-B412-E08381A144E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E53B4797-FCFE-418E-B412-E08381A144E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E53B4797-FCFE-418E-B412-E08381A144E3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1D5D5D3E-2D9A-4AAB-896E-E0957CD75E9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D5D5D3E-2D9A-4AAB-896E-E0957CD75E9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D5D5D3E-2D9A-4AAB-896E-E0957CD75E9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D5D5D3E-2D9A-4AAB-896E-E0957CD75E9A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0A24B96A-7B80-486A-9546-B82FC5F99675}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0A24B96A-7B80-486A-9546-B82FC5F99675}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0A24B96A-7B80-486A-9546-B82FC5F99675}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0A24B96A-7B80-486A-9546-B82FC5F99675}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BCBB643F-C468-4EE6-B186-6E2084B644DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BCBB643F-C468-4EE6-B186-6E2084B644DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BCBB643F-C468-4EE6-B186-6E2084B644DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BCBB643F-C468-4EE6-B186-6E2084B644DE}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {F98A62EA-62A5-4385-9709-B488076B1543}
+ EndGlobalSection
+EndGlobal
diff --git a/Services/Games/Extentions/ServiceCollectionExtentions.cs b/Services/Games/Extentions/ServiceCollectionExtentions.cs
new file mode 100644
index 0000000..23f950c
--- /dev/null
+++ b/Services/Games/Extentions/ServiceCollectionExtentions.cs
@@ -0,0 +1,14 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Services.Tickets.Extentions;
+
+namespace Services.Games.Extentions;
+
+public static class ServiceCollectionExtentions
+{
+ public static void TyAddGamesService(this IServiceCollection services)
+ {
+ services.TyAddTicketService();
+ services.TryAddScoped();
+ }
+}
diff --git a/Services/Games/GameService.cs b/Services/Games/GameService.cs
new file mode 100644
index 0000000..91c5c03
--- /dev/null
+++ b/Services/Games/GameService.cs
@@ -0,0 +1,49 @@
+using Microsoft.Extensions.Logging;
+using Services.Numbers;
+using Services.Tickets;
+using Services.Tickets.Models;
+using System.Net.Sockets;
+
+namespace Services.Games;
+internal class GameService : IGameService
+{
+ private readonly INumbersService _numbersService;
+ private readonly ITicketService _ticketService;
+
+ public GameService(ILogger logger, INumbersService numbersService, ITicketService ticketService)
+ {
+ _numbersService = numbersService;
+ _ticketService = ticketService;
+ }
+
+ public async Task winTickets, int matches)>> GetWinnersTickets(byte[] winNumbers)
+ {
+ List tickets = await _ticketService.GetAllTickets();
+ return CalculateWinners(tickets, winNumbers);
+
+ }
+
+ private List<(List winTickets,int matches)> CalculateWinners(List tickets, byte[] bytes)
+ {
+ List<(List winTickets,int matches)> results = new();
+ for (int i = 0; i < bytes.Length; i++)
+ {
+ List winners = new List();
+ for (int j = 0; j < tickets.Count; j++)
+ {
+ if (bytes.Except(tickets[j].Numbers!).Count() == i)
+ {
+ winners.Add(tickets[j]);
+ tickets.RemoveAt(j);
+ }
+ }
+ results.Add((winners, bytes.Length - i));
+ }
+ return results;
+ }
+
+ public byte[] GetWinNumbers()
+ {
+ return _numbersService.GetNumbers(6);
+ }
+}
diff --git a/Services/Games/IGameService.cs b/Services/Games/IGameService.cs
new file mode 100644
index 0000000..1556ef6
--- /dev/null
+++ b/Services/Games/IGameService.cs
@@ -0,0 +1,9 @@
+using Services.Tickets.Models;
+
+namespace Services.Games;
+
+public interface IGameService
+{
+ byte[] GetWinNumbers();
+ Task winTickets, int matches)>> GetWinnersTickets(byte[] winNumbers);
+}
diff --git a/Services/Numbers/Extentions/ServiceCollectionExtentions.cs b/Services/Numbers/Extentions/ServiceCollectionExtentions.cs
new file mode 100644
index 0000000..0dbe501
--- /dev/null
+++ b/Services/Numbers/Extentions/ServiceCollectionExtentions.cs
@@ -0,0 +1,12 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace Services.Numbers.Extentions;
+
+public static class ServiceCollectionExtentions
+{
+ public static void TyAddNumbersService(this IServiceCollection services)
+ {
+ services.TryAddScoped();
+ }
+}
diff --git a/Services/Numbers/INumbersService.cs b/Services/Numbers/INumbersService.cs
new file mode 100644
index 0000000..29e5d06
--- /dev/null
+++ b/Services/Numbers/INumbersService.cs
@@ -0,0 +1,6 @@
+namespace Services.Numbers;
+
+public interface INumbersService
+{
+ byte[] GetNumbers(byte count);
+}
diff --git a/Services/Numbers/NumbersService.cs b/Services/Numbers/NumbersService.cs
new file mode 100644
index 0000000..4e47909
--- /dev/null
+++ b/Services/Numbers/NumbersService.cs
@@ -0,0 +1,49 @@
+namespace Services.Numbers;
+
+internal class NumbersService : INumbersService
+{
+ public byte[] GetNumbers(byte count = 6)
+ {
+ byte[] init =
+ [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ 34,
+ 35,
+ 36
+ ];
+ Random.Shared.Shuffle(init);
+ return init.Take(count).ToArray();
+ }
+}
diff --git a/Services/Services.csproj b/Services/Services.csproj
new file mode 100644
index 0000000..94f6f9e
--- /dev/null
+++ b/Services/Services.csproj
@@ -0,0 +1,20 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+ <_Parameter1>Lottery.Tests
+
+
+
+
diff --git a/Services/Tickets/Extentions/ServiceCollectionExtentions.cs b/Services/Tickets/Extentions/ServiceCollectionExtentions.cs
new file mode 100644
index 0000000..7eb8fcc
--- /dev/null
+++ b/Services/Tickets/Extentions/ServiceCollectionExtentions.cs
@@ -0,0 +1,14 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Services.Numbers.Extentions;
+
+namespace Services.Tickets.Extentions;
+
+public static class ServiceCollectionExtentions
+{
+ public static void TyAddTicketService(this IServiceCollection services)
+ {
+ services.TyAddNumbersService();
+ services.TryAddScoped();
+ }
+}
diff --git a/Services/Tickets/ITicketRepository.cs b/Services/Tickets/ITicketRepository.cs
new file mode 100644
index 0000000..6ac10a1
--- /dev/null
+++ b/Services/Tickets/ITicketRepository.cs
@@ -0,0 +1,8 @@
+using Services.Tickets.Models;
+
+namespace Services.Tickets;
+public interface ITicketRepository
+{
+ Task AddNewTicket(LotteryTicket ticket);
+ Task> GetAllTickets();
+}
diff --git a/Services/Tickets/ITicketService.cs b/Services/Tickets/ITicketService.cs
new file mode 100644
index 0000000..a524460
--- /dev/null
+++ b/Services/Tickets/ITicketService.cs
@@ -0,0 +1,9 @@
+using Services.Tickets.Models;
+
+namespace Services.Tickets;
+
+public interface ITicketService
+{
+ Task> GetAllTickets();
+ Task GetNewTicket();
+}
diff --git a/Services/Tickets/Models/LotteryTicket.cs b/Services/Tickets/Models/LotteryTicket.cs
new file mode 100644
index 0000000..eba2468
--- /dev/null
+++ b/Services/Tickets/Models/LotteryTicket.cs
@@ -0,0 +1,8 @@
+namespace Services.Tickets.Models;
+public class LotteryTicket
+{
+ public long? Id { get; set; }
+ public byte[]? Numbers { get; set; }
+ public string? Owner { get; set; }
+ public string? PhoneNumber { get; set; }
+}
diff --git a/Services/Tickets/TicketService.cs b/Services/Tickets/TicketService.cs
new file mode 100644
index 0000000..284ba48
--- /dev/null
+++ b/Services/Tickets/TicketService.cs
@@ -0,0 +1,36 @@
+using Microsoft.Extensions.Logging;
+using Services.Numbers;
+using Services.Tickets.Models;
+
+namespace Services.Tickets;
+
+internal class TicketService : ITicketService
+{
+ private readonly ILogger _logger;
+ private readonly ITicketRepository _ticketRepository;
+ private readonly INumbersService _numbersService;
+
+ public TicketService(ILogger logger, ITicketRepository ticketRepository, INumbersService numbersService)
+ {
+ _logger = logger;
+ _ticketRepository = ticketRepository;
+ _numbersService = numbersService;
+ }
+
+ public Task> GetAllTickets()
+ {
+ return _ticketRepository.GetAllTickets();
+ }
+
+ public async Task GetNewTicket()
+ {
+ LotteryTicket ticket = new()
+ {
+ Numbers = _numbersService.GetNumbers(6)
+ };
+ var id = await _ticketRepository.AddNewTicket(ticket);
+ ticket.Id = id;
+ //_logger.LogInformation("New ticket created");
+ return ticket;
+ }
+}
diff --git a/WorkerService1/Program.cs b/WorkerService1/Program.cs
new file mode 100644
index 0000000..8a63434
--- /dev/null
+++ b/WorkerService1/Program.cs
@@ -0,0 +1,13 @@
+using WorkerService1;
+using Data.Extentions;
+using Services.Tickets.Extentions;
+using Services.Games.Extentions;
+
+var builder = Host.CreateApplicationBuilder(args);
+builder.Services.AddHostedService();
+builder.Services.TyAddTicketService();
+builder.Services.TyAddGamesService();
+builder.Services.TyAddFakeTicketRepository();
+
+var host = builder.Build();
+host.Run();
diff --git a/WorkerService1/Properties/launchSettings.json b/WorkerService1/Properties/launchSettings.json
new file mode 100644
index 0000000..e5d9dbd
--- /dev/null
+++ b/WorkerService1/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "WorkerService1": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "environmentVariables": {
+ "DOTNET_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/WorkerService1/Worker.cs b/WorkerService1/Worker.cs
new file mode 100644
index 0000000..1aaf66c
--- /dev/null
+++ b/WorkerService1/Worker.cs
@@ -0,0 +1,32 @@
+using Services.Games;
+using Services.Tickets;
+
+namespace WorkerService1;
+
+public class Worker : BackgroundService
+{
+ private readonly ILogger _logger;
+ private readonly IServiceScopeFactory _serviceScopeFactory;
+
+ public Worker(ILogger logger, IServiceScopeFactory serviceScopeFactory)
+ {
+ _logger = logger;
+ _serviceScopeFactory = serviceScopeFactory;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ using (var scope = _serviceScopeFactory.CreateScope())
+ {
+ var ticketService = scope.ServiceProvider.GetRequiredService();
+ for (int i = 0; i < 100000; i++)
+ {
+ var ticket = await ticketService.GetNewTicket();
+ }
+
+ var gameService = scope.ServiceProvider.GetRequiredService();
+ var winNumbers = gameService.GetWinNumbers();
+ var winners = await gameService.GetWinnersTickets(winNumbers);
+ }
+ }
+}
diff --git a/WorkerService1/WorkerService1.csproj b/WorkerService1/WorkerService1.csproj
new file mode 100644
index 0000000..c9a09ad
--- /dev/null
+++ b/WorkerService1/WorkerService1.csproj
@@ -0,0 +1,18 @@
+
+
+
+ net8.0
+ enable
+ enable
+ dotnet-WorkerService1-a5282c60-3d37-46ee-983b-990e33b39645
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WorkerService1/appsettings.Development.json b/WorkerService1/appsettings.Development.json
new file mode 100644
index 0000000..b2dcdb6
--- /dev/null
+++ b/WorkerService1/appsettings.Development.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
diff --git a/WorkerService1/appsettings.json b/WorkerService1/appsettings.json
new file mode 100644
index 0000000..b2dcdb6
--- /dev/null
+++ b/WorkerService1/appsettings.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}