diff --git a/src/Services/e-sender/O2NextGen.ESender.Api.sln b/src/Services/e-sender/O2NextGen.ESender.Api.sln index 767412b9..032a97e4 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api.sln +++ b/src/Services/e-sender/O2NextGen.ESender.Api.sln @@ -5,6 +5,10 @@ VisualStudioVersion = 25.0.1700.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "O2NextGen.ESender.Api", "O2NextGen.ESender.Api\O2NextGen.ESender.Api.csproj", "{89FADD48-B8C5-4923-AA5C-D9FFF0B21E87}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "O2NextGen.ESender.Business", "O2NextGen.ESender.Business\O2NextGen.ESender.Business.csproj", "{AEB3AF96-A144-41F3-9F9D-715476640C42}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "O2NextGen.ESender.Impl", "O2NextGen.ESender.Impl\O2NextGen.ESender.Impl.csproj", "{912084D1-1E1A-4170-A345-375621788E06}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +19,14 @@ Global {89FADD48-B8C5-4923-AA5C-D9FFF0B21E87}.Debug|Any CPU.Build.0 = Debug|Any CPU {89FADD48-B8C5-4923-AA5C-D9FFF0B21E87}.Release|Any CPU.ActiveCfg = Release|Any CPU {89FADD48-B8C5-4923-AA5C-D9FFF0B21E87}.Release|Any CPU.Build.0 = Release|Any CPU + {AEB3AF96-A144-41F3-9F9D-715476640C42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AEB3AF96-A144-41F3-9F9D-715476640C42}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AEB3AF96-A144-41F3-9F9D-715476640C42}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AEB3AF96-A144-41F3-9F9D-715476640C42}.Release|Any CPU.Build.0 = Release|Any CPU + {912084D1-1E1A-4170-A345-375621788E06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {912084D1-1E1A-4170-A345-375621788E06}.Debug|Any CPU.Build.0 = Debug|Any CPU + {912084D1-1E1A-4170-A345-375621788E06}.Release|Any CPU.ActiveCfg = Release|Any CPU + {912084D1-1E1A-4170-A345-375621788E06}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/Controllers/EmailSenderController.cs b/src/Services/e-sender/O2NextGen.ESender.Api/Controllers/EmailSenderController.cs index 3001cd27..ffb380f1 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/Controllers/EmailSenderController.cs +++ b/src/Services/e-sender/O2NextGen.ESender.Api/Controllers/EmailSenderController.cs @@ -1,8 +1,12 @@ using System.Collections.Generic; using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using O2NextGen.ESender.Api.Helpers; +using O2NextGen.ESender.Api.Mappings; using O2NextGen.ESender.Api.Models; +using O2NextGen.ESender.Business.Services; namespace O2NextGen.ESender.Api.Controllers { @@ -10,39 +14,38 @@ namespace O2NextGen.ESender.Api.Controllers public class EmailSenderController : Controller { private readonly IEmailSender _emailSender; + private readonly IEmailSenderService _emailSenderService; - public EmailSenderController(IEmailSender emailSender) + public EmailSenderController(IEmailSender emailSender, IEmailSenderService emailSenderService) { _emailSender = emailSender; + _emailSenderService = emailSenderService; } - private static long _currentCertificateId = 1; - - private static List _mailLetters = new List() - { - new MailViewModel() {Id = 1, From ="from@eexample.com",To = "example@eexample.com", Subject="theme", Body="

last

"}, - new MailViewModel() {Id = 2, From ="from@eexample.com",To = "example@eexample.com", Subject="theme", Body="

last

"}, - }; [HttpGet] [Route("")] - public IActionResult Index() => View(_mailLetters); + public async Task Index() + { + var models = await _emailSenderService.GetAllAsync(CancellationToken.None); + return View(models.ToViewModel()); + } [HttpGet] [Route("{id}")] - public IActionResult Detail(long id) + public async Task Detail(long id) { - var certificate = _mailLetters.SingleOrDefault(_ => _.Id == id); - if (certificate == null) + var emailRequest =await _emailSenderService.GetByIdAsync(id, CancellationToken.None); + if (emailRequest == null) return NotFound(); - return View(certificate); + return View(emailRequest.ToViewModel()); } [HttpPost] [Route("id")] [ValidateAntiForgeryToken] - public IActionResult Edit(long id, MailViewModel model) + public async Task Edit(long id, MailRequestViewModel model) { - var certificate = _mailLetters.SingleOrDefault(_ => _.Id == id); + var certificate = await _emailSenderService.GetByIdAsync(id, CancellationToken.None); if (certificate == null) return NotFound(); certificate.From = model.From; @@ -62,11 +65,10 @@ public IActionResult Create() [HttpPost] [Route("")] - public IActionResult CreateReally(MailViewModel model) + public async Task CreateReally(MailRequestViewModel model) { - model.Id = _currentCertificateId++; - _mailLetters.Add(model); - _emailSender.Send(model.To, model.Subject, model.Body); + var emailRequest = await _emailSenderService.AddAsync(model.ToModel(), CancellationToken.None); + await _emailSender.Send(model.To, model.Subject, model.Body); return RedirectToAction("Index"); } } diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/IoC/ServiceCollectionExtensions.cs b/src/Services/e-sender/O2NextGen.ESender.Api/IoC/ServiceCollectionExtensions.cs index 44d9a11e..8ee99a4c 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/IoC/ServiceCollectionExtensions.cs +++ b/src/Services/e-sender/O2NextGen.ESender.Api/IoC/ServiceCollectionExtensions.cs @@ -1,6 +1,9 @@ using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using O2NextGen.ESender.Api.Helpers; +using O2NextGen.ESender.Business.Services; +using O2NextGen.ESender.Impl.Services; namespace O2NextGen.ESender.Api.IoC { @@ -21,5 +24,15 @@ public static TConfig ConfigurePOCO(this IServiceCollection services, I services.AddSingleton(config); return config; } + public static IServiceCollection AddBusiness(this IServiceCollection services) + { + services.AddSingleton(); + // Include DataLayer + // services.AddScoped(); + //more business services... + + services.AddSingleton(); + return services; + } } } \ No newline at end of file diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/Mappings/EmailRequestMappings.cs b/src/Services/e-sender/O2NextGen.ESender.Api/Mappings/EmailRequestMappings.cs new file mode 100644 index 00000000..e2b0e6b8 --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Api/Mappings/EmailRequestMappings.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using O2NextGen.ESender.Api.Models; +using O2NextGen.ESender.Business.Models; + +namespace O2NextGen.ESender.Api.Mappings +{ + public static class EmailRequestMappings + { + public static MailRequestViewModel ToViewModel(this EmailRequest model) + { + if (model == null) + return null; + + var viewModel = new MailRequestViewModel(); + + //Bindings + viewModel.Id = model.Id; + viewModel.From = model.From; + viewModel.To = model.To; + viewModel.Subject = model.Subject; + viewModel.Body = model.Body; + + return viewModel; + } + + public static EmailRequest ToModel(this MailRequestViewModel requestViewModel) + { + if (requestViewModel == null) + return null; + + var model = new EmailRequest(); + + //Bindings + model.Id = requestViewModel.Id; + model.From = requestViewModel.From; + model.To = requestViewModel.To; + model.Subject = requestViewModel.Subject; + model.Body = requestViewModel.Body; + + return model; + } + + public static IReadOnlyCollection ToViewModel( + this IReadOnlyCollection models) + { + if (models.Count == 0) + { + return Array.Empty(); + } + + var subscription = new MailRequestViewModel[models.Count]; + var i = 0; + foreach (var model in models) + { + subscription[i] = ToViewModel(model); + ++i; + } + + return new ReadOnlyCollection(subscription); + } + } +} \ No newline at end of file diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/Models/MailViewModel.cs b/src/Services/e-sender/O2NextGen.ESender.Api/Models/MailRequestViewModel.cs similarity index 88% rename from src/Services/e-sender/O2NextGen.ESender.Api/Models/MailViewModel.cs rename to src/Services/e-sender/O2NextGen.ESender.Api/Models/MailRequestViewModel.cs index 105c3306..23b38665 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/Models/MailViewModel.cs +++ b/src/Services/e-sender/O2NextGen.ESender.Api/Models/MailRequestViewModel.cs @@ -1,7 +1,7 @@ using System; namespace O2NextGen.ESender.Api.Models { - public class MailViewModel + public class MailRequestViewModel { public long Id { get; set; } public string From { get; set; } diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/O2NextGen.ESender.Api.csproj b/src/Services/e-sender/O2NextGen.ESender.Api/O2NextGen.ESender.Api.csproj index 79739fb9..505d3612 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/O2NextGen.ESender.Api.csproj +++ b/src/Services/e-sender/O2NextGen.ESender.Api/O2NextGen.ESender.Api.csproj @@ -32,4 +32,9 @@ + + + + + diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/Startup.cs b/src/Services/e-sender/O2NextGen.ESender.Api/Startup.cs index 927a8519..4d78a1aa 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/Startup.cs +++ b/src/Services/e-sender/O2NextGen.ESender.Api/Startup.cs @@ -21,8 +21,8 @@ public Startup(IConfiguration appConfiguration) public void ConfigureServices(IServiceCollection services) { services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + services.AddBusiness(); services.ConfigurePOCO(AppConfiguration.GetSection("Sender")); - services.AddSingleton(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Create.cshtml b/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Create.cshtml index 1c406818..4ed455cc 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Create.cshtml +++ b/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Create.cshtml @@ -1,4 +1,4 @@ -@model MailViewModel +@model MailRequestViewModel
diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Detail.cshtml b/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Detail.cshtml index 084d6d08..ee3fb28c 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Detail.cshtml +++ b/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Detail.cshtml @@ -1,5 +1,5 @@  -@model MailViewModel +@model MailRequestViewModel diff --git a/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Index.cshtml b/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Index.cshtml index 017c8792..65f66232 100644 --- a/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Index.cshtml +++ b/src/Services/e-sender/O2NextGen.ESender.Api/Views/EmailSender/Index.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @foreach (var certificate in Model) { diff --git a/src/Services/e-sender/O2NextGen.ESender.Business/Models/EmailRequest.cs b/src/Services/e-sender/O2NextGen.ESender.Business/Models/EmailRequest.cs new file mode 100644 index 00000000..f1f6dab4 --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Business/Models/EmailRequest.cs @@ -0,0 +1,11 @@ +namespace O2NextGen.ESender.Business.Models +{ + public class EmailRequest + { + public long Id { get; set; } + public string From { get; set; } + public string To { get; set; } + public string Subject { get; set; } + public string Body { get; set; } + } +} \ No newline at end of file diff --git a/src/Services/e-sender/O2NextGen.ESender.Business/O2NextGen.ESender.Business.csproj b/src/Services/e-sender/O2NextGen.ESender.Business/O2NextGen.ESender.Business.csproj new file mode 100644 index 00000000..17ca88b0 --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Business/O2NextGen.ESender.Business.csproj @@ -0,0 +1,7 @@ + + + + netcoreapp2.2 + + + diff --git a/src/Services/e-sender/O2NextGen.ESender.Business/Services/IEmailSenderService.cs b/src/Services/e-sender/O2NextGen.ESender.Business/Services/IEmailSenderService.cs new file mode 100644 index 00000000..6b98147e --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Business/Services/IEmailSenderService.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using O2NextGen.ESender.Business.Models; + +namespace O2NextGen.ESender.Business.Services +{ + public interface IEmailSenderService + { + Task> GetAllAsync(CancellationToken ct); + + Task GetByIdAsync(long id, CancellationToken ct); + + Task UpdateAsync(EmailRequest emailRequest, CancellationToken ct); + + Task AddAsync(EmailRequest emailRequest, CancellationToken ct); + + Task RemoveAsync(long id, CancellationToken ct); + } +} \ No newline at end of file diff --git a/src/Services/e-sender/O2NextGen.ESender.Impl/Mappings/EmailRequestMappings.cs b/src/Services/e-sender/O2NextGen.ESender.Impl/Mappings/EmailRequestMappings.cs new file mode 100644 index 00000000..36ca2fca --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Impl/Mappings/EmailRequestMappings.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using O2NextGen.ESender.Business.Models; + +namespace O2NextGen.ESender.Impl.Mappings +{ + // + // { + // public static EmailRequest ToService(this EmailRequest entity) + // { + // return entity != null ? new EmailRequest() {Id = entity.Id, Name = entity.Name} : null; + // } + // + // public static EmailRequestEntity ToEntity(this EmailRequest model) + // { + // return model != null ? new EmailRequestEntity() {Id = model.Id, Name = model.Name} : null; + // } + // + // public static IReadOnlyCollection + // ToService(this IReadOnlyCollection entities) => + // entities.MapCollection(ToService); + // } +} \ No newline at end of file diff --git a/src/Services/e-sender/O2NextGen.ESender.Impl/Mappings/MappingExtensions.cs b/src/Services/e-sender/O2NextGen.ESender.Impl/Mappings/MappingExtensions.cs new file mode 100644 index 00000000..7c0289c7 --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Impl/Mappings/MappingExtensions.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; + +namespace O2NextGen.ESender.Impl.Mappings +{ + internal static class MappingExtensions + { + public static IReadOnlyCollection MapCollection(this IReadOnlyCollection input, + Func mapper) + { + if (mapper is null) + { + throw new ArgumentNullException(nameof(mapper)); + } + + if (input is null || input.Count == 0) + { + return Array.Empty(); + } + + var output = new TOut[input.Count]; + var i = 0; + foreach (var entity in input) + { + output[i] = mapper(entity); + i++; + } + + return new ReadOnlyCollection(output); + } + } +} \ No newline at end of file diff --git a/src/Services/e-sender/O2NextGen.ESender.Impl/O2NextGen.ESender.Impl.csproj b/src/Services/e-sender/O2NextGen.ESender.Impl/O2NextGen.ESender.Impl.csproj new file mode 100644 index 00000000..f3333786 --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Impl/O2NextGen.ESender.Impl.csproj @@ -0,0 +1,11 @@ + + + + netcoreapp2.2 + + + + + + + diff --git a/src/Services/e-sender/O2NextGen.ESender.Impl/Services/InMemoryEmailSenderService.cs b/src/Services/e-sender/O2NextGen.ESender.Impl/Services/InMemoryEmailSenderService.cs new file mode 100644 index 00000000..90c1a701 --- /dev/null +++ b/src/Services/e-sender/O2NextGen.ESender.Impl/Services/InMemoryEmailSenderService.cs @@ -0,0 +1,81 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using O2NextGen.ESender.Business.Models; +using O2NextGen.ESender.Business.Services; + +namespace O2NextGen.ESender.Impl.Services +{ + + public class InMemoryEmailSenderService : IEmailSenderService + { + #region Fields + + private static readonly List Certificates = new List() + { + new EmailRequest() + { + Id = 1, From = "from@eexample.com", To = "example@eexample.com", Subject = "theme", + Body = "

last

" + } + }; + + private long _currentId; + + #endregion + + #region Ctors + + public InMemoryEmailSenderService() + { + _currentId = Certificates.Count(); + } + + #endregion + + #region Methods + + public async Task> GetAllAsync(CancellationToken ct) + { + await Task.Delay(3000, ct); + return await Task.FromResult>(Certificates.AsReadOnly()); + } + + public async Task GetByIdAsync(long id, CancellationToken ct) + { + await Task.Delay(3000, ct); + return await Task.FromResult(Certificates.SingleOrDefault(g => g.Id == id)); + } + + public async Task UpdateAsync(EmailRequest certificate, CancellationToken ct) + { + await Task.Delay(5000, ct); + var toUpdate = Certificates.SingleOrDefault(g => g.Id == certificate.Id); + if (toUpdate == null) + return null; + + toUpdate.From = certificate.From; + toUpdate.To = certificate.To; + toUpdate.Subject = certificate.Subject; + toUpdate.Body = certificate.Body; + + return await Task.FromResult(toUpdate); + } + + public async Task AddAsync(EmailRequest certificate, CancellationToken ct) + { + await Task.Delay(3000, ct); + certificate.Id = ++_currentId; + Certificates.Add(certificate); + return await Task.FromResult(certificate); + } + + public Task RemoveAsync(long id, CancellationToken ct) + { + throw new System.NotImplementedException(); + } + + #endregion + } +} \ No newline at end of file