Compare commits

...

31 Commits

Author SHA1 Message Date
f5e02c4219 bump to 3.2.0 2025-09-04 16:28:07 +02:00
b88106a38f feat(EmailOut): add Attachment1Bytes, Att1RelatedId and Att1RelType properties. 2025-09-04 16:26:23 +02:00
Developer 02
f70794b7b0 chore: Upgrade von DigitalData.EmailProfilerDispatcher und DigitalData.EmailProfilerDispatcher.Abstraction auf 3.1.1 2025-05-27 18:52:47 +02:00
Developer 02
1157ea032b refaktorisieren: Ersetzen Sie Application.Abstraction durch Abstraction.Application 2025-05-27 18:42:36 +02:00
Developer 02
fd698e7a5d chore(Abstraktion.Attribute): konfiguriert für die Verpackung 2025-05-20 16:50:21 +02:00
Developer 02
a54ec39df7 chore(Abstraktion.Attribute): Unterstützung für .net framework 4.6.2 hinzufügen 2025-05-20 16:39:19 +02:00
Developer 02
8fc23b0055 feat(Abstraction.Attributes): als separates Projekt erstellt, um .net framework als Ziel hinzuzufügen 2025-05-20 16:35:30 +02:00
Developer 02
e372a5a5b2 chore: Pakete aktualisieren und Konflikte lösen 2025-05-20 16:32:13 +02:00
Developer 02
bb9a64a85b Remove old icon and update project references
- Deleted the binary file `icon.png`.
- Updated `PackageIcon` paths in project files to remove dependency on `Assets\icon.png`.
- Added a new `None` item in `DigitalData.EmailProfilerDispatcher.Abstraction.csproj` to include `..\Assets\icon.png`.
- Created a new project section for "Solution Items" in `DigitalData.EmailProfilerDispatcher.sln` to include `icon.png`.
- Removed the previous `ItemGroup` for `None` that updated `Assets\icon.png`.
- The binary file `icon.png` was replaced with a new version.
2025-05-16 10:01:30 +02:00
Developer 02
ab40ce9205 chore: Version auf 3.0.0 für EmailProfilerDispatcher
Aktualisiert die Versionsnummer von 2.0.0 auf 3.0.0 sowohl in
`DigitalData.EmailProfilerDispatcher.Abstraction.csproj`
als auch in `DigitalData.EmailProfilerDispatcher.csproj`.
Setzen Sie `FileVersion` und `AssemblyVersion` auf 3.0.0,
, um eine wesentliche Aktualisierung des Pakets anzuzeigen.
2025-04-14 16:52:07 +02:00
Developer 02
863bf43873 chore: Zielframeworks für Kompatibilität aktualisieren
Aktualisierte das Zielframework von `net7.0` auf mehrere Frameworks (`net7.0;net8.0;net9.0`). Diese Änderung verbessert die Kompatibilität und macht die Projekte zukunftssicher für die .NET-Versionen 7.0, 8.0 und 9.0.
2025-04-14 16:49:05 +02:00
Developer 02
b953e3afaa Refactor email repository and service interfaces
- Die Schnittstelle `IEmailOutRepository` wurde durch Entfernen unnötiger Klammern gestrafft.
- Aktualisierte `IEmailOutService` Schnittstelle, um generische Parameter zu korrigieren und Redundanz zu entfernen.
- Aktualisierte Paketversionen in Projektdateien auf `DigitalData.Core.Abstractions` (3.4.0) und `DigitalData.Core.Application` (3.2.0).
- Verbesserte `CreateWithTemplateAsync` Methoden in `EmailOutService.cs` für bessere Implementierung.
- Das Testprojekt wurde aktualisiert, um die neue Paketversion für `DigitalData.Core.Application` zu berücksichtigen.
2025-04-14 16:38:52 +02:00
Developer 02
211a63d70e chore(release): Projektpaketversion auf 2.0.0.0 aktualisiert 2024-09-19 20:24:11 +02:00
Developer 02
184accafd5 chore(deps): update package in test project 2024-09-19 20:12:33 +02:00
Developer 02
3665a20841 chore(deps): Core-Pakete auf Version 2.0.0.0 aktualisiert 2024-09-19 16:41:40 +02:00
Developer 02
025a21d13a Paket-Symbol aktualisieren 2024-07-01 15:24:34 +02:00
Developer 02
49cb078ac9 Konfiguriert für das Nuget-Paket 2024-07-01 15:21:46 +02:00
Developer 02
a56ede375d Refactor: Projekt von DigitalData.EmailProfilerDispatcher.Application in DigitalData.EmailProfilerDispatcher umbenannt, um die Struktur zu vereinfachen und die Abstraktion zu verbessern 2024-07-01 14:52:54 +02:00
Developer 02
d18b6df9f7 Die Infrastrukturschicht wurde mit der Anwendungsschicht zusammengeführt, um das Projekt zu vereinfachen, und Abstraktion wurde hinzugefügt. 2024-07-01 14:31:38 +02:00
Developer 02
619b1e414b Gitignore aktualisieren 2024-07-01 13:06:31 +02:00
Developer 02
d9320f2816 Gitignore aktualisieren 2024-07-01 13:06:26 +02:00
Developer 02
e05e969562 API entfernen. 2024-07-01 13:05:27 +02:00
Developer 02
379f24e589 Nuget-Paket 'Core' integriert 2024-06-23 00:27:43 +02:00
Developer 02
251490ebc4 Die Service-Schnittstellen wurden überarbeitet, um den generischen Repository-Parameter zur Vereinfachung und besseren Lesbarkeit zu entfernen. 2024-06-15 00:52:06 +02:00
Developer 02
76b4aafe0c Aktualisierte Vererbung von CRUD Service. 2024-06-14 14:29:22 +02:00
Developer 02
aba93f1dd4 NotMapped-Attribut zur AddedWhen-Eigenschaft hinzugefügt, damit MSSQL automatisch zuweisen kann. 2024-06-12 00:26:32 +02:00
Developer 02
e22d030fa2 FillTemplate-Methode als Erweiterung hinzugefügt. Option zum Schreiben von Platzhaltern als Wörterbuch hinzugefügt. 2024-06-10 16:19:48 +02:00
Developer 02
a8b3e88f09 Update test 2024-06-10 15:44:12 +02:00
Developer 02
a2bd369ed1 feat: E-Mail-Vorlagenverarbeitung hinzufügen
- Methode `FillTemplate` für Platzhalterersetzung hinzugefügt.
- `TemplatePlaceholderAttribute` eingeführt.
- `EmailOutService` mit Vorlagenmethoden aktualisiert.
- Unit-Tests für Vorlagenverarbeitung hinzugefügt.
2024-06-10 14:16:54 +02:00
Developer 02
1adc0c4d93 Refaktorisierter EmailOutService zur Unterstützung generischer Lokalisierungsressourcen durch Hinzufügen eines generischen Parameters zur Klasse und Aktualisierung des Konstruktors. 2024-05-22 09:49:02 +02:00
Developer 02
02afdfbd0f Unnötige Nougat-Pakete entfernt. EFCore-Version auf 7.0.16 herabgestuft. 2024-05-22 09:31:55 +02:00
41 changed files with 503 additions and 619 deletions

1
.gitignore vendored
View File

@@ -398,3 +398,4 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
/DigitalData.EmailProfilerDispatcher.API/

BIN
Assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -1,15 +0,0 @@
using DigitalData.Core.API;
using DigitalData.EmailProfilerDispatcher.Application.Contracts;
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
namespace DigitalData.EmailProfilerGateway.API.Controllers
{
public class MailController : CRUDControllerBase<IEmailOutService, IEmailOutRepository, EmailOutCreateDto, EmailOutDto, EmailOutDto, EmailOut, int>
{
public MailController(ILogger<MailController> logger, IEmailOutService service) : base(logger, service)
{
}
}
}

View File

@@ -1,47 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.15" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.19" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.19" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Application\DigitalData.EmailProfilerDispatcher.Application.csproj" />
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Domain\DigitalData.EmailProfilerDispatcher.Domain.csproj" />
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Infrastructure\DigitalData.EmailProfilerDispatcher.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="DigitalData.Core.API">
<HintPath>..\..\WebCoreModules\DigitalData.Core.API\bin\Debug\net7.0\DigitalData.Core.API.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.Contracts">
<HintPath>..\..\WebCoreModules\DigitalData.Core.API\bin\Debug\net7.0\DigitalData.Core.Contracts.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.DTO">
<HintPath>..\..\WebCoreModules\DigitalData.Core.API\bin\Debug\net7.0\DigitalData.Core.DTO.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -1,40 +0,0 @@
using DigitalData.Core.API;
using DigitalData.EmailProfilerDispatcher.API.Resources;
using DigitalData.EmailProfilerDispatcher.Application;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
var builder = WebApplication.CreateBuilder(args);
var config = builder.Configuration;
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddCookieBasedLocalizer();
builder.Services.AddDispatcher(options => options.UseSqlServer(config.GetConnectionString("Default")));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddSingleton<IStringLocalizer, StringLocalizer<Resource>>();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
app.UseAuthorization();
app.UseCookieBasedLocalizer("de-DE", "en-US");
app.MapControllers();
app.Run();

View File

@@ -1,41 +0,0 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:6499",
"sslPort": 44381
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5231",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7115;http://localhost:5231",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -1,6 +0,0 @@
namespace DigitalData.EmailProfilerDispatcher.API.Resources
{
public class Resource
{
}
}

View File

@@ -1,101 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,101 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -1,8 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

View File

@@ -1,12 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"Default": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;"
}
}

View File

@@ -0,0 +1,57 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net462;net7.0;net8.0;net9.0</TargetFrameworks>
<PackageId>DigitalData.EmailProfilerDispatcher.Abstraction.Attributes</PackageId>
<Company>Digital Data GmbH</Company>
<Copyright>Copyright 2025</Copyright>
<PackageIcon>icon.png</PackageIcon>
<PackageTags>digital data email dispatcher</PackageTags>
<Description>This package provides the necessary Attributes for the DigitalData.EmailProfilerDispatcher.Abstractions library to support the .NET Framrwork.</Description>
<Authors>Digital Data GmbH</Authors>
<RepositoryUrl>http://git.dd:3000/AppStd/EmailProfilerDispatcher.git</RepositoryUrl>
<Version>1.0.0</Version>
<AssemblyVersion>1.0.0</AssemblyVersion>
<FileVersion>1.0.0</FileVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net462'">
<ImplicitUsings>disable</ImplicitUsings>
<LangVersion>7.3</LangVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' != 'net462'">
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net462'">
<PackageReference Include="System.ComponentModel.Annotations" Version="4.7.0" />
</ItemGroup>
<ItemGroup>
<None Include="..\Assets\icon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="DigitalData.Core.Abstractions.Security">
<Version>1.0.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="DigitalData.Core.Abstractions.Security">
<Version>1.0.0</Version>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="DigitalData.Core.Abstractions.Security">
<Version>1.0.0</Version>
</PackageReference>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,17 @@
#if NETFRAMEWORK
using System;
#endif
namespace DigitalData.EmailProfilerDispatcher.Abstraction.Attributes
{
[AttributeUsage(AttributeTargets.Property)]
public class TemplatePlaceholderAttribute : Attribute
{
public readonly string Placeholder;
public TemplatePlaceholderAttribute(string placeholder)
{
Placeholder = placeholder;
}
}
}

View File

@@ -0,0 +1,9 @@
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
namespace DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
[Obsolete("Use IRepository")]
public interface IEmailOutRepository : ICRUDRepository<EmailOut, int>
{
}

View File

@@ -0,0 +1,12 @@
using DigitalData.Core.Abstraction.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
namespace DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
[Obsolete("Use MediatR")]
public interface IEmailOutService : ICRUDService<EmailOutCreateDto, EmailOutDto, EmailOut, int>
{
Task<DataResult<int>> CreateWithTemplateAsync(EmailOutCreateDto createDto, params object[] models);
}

View File

@@ -0,0 +1,25 @@
namespace DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut
{
public record EmailOutCreateDto
{
public int ReminderTypeId { get; set; }
public int SendingProfile { get; set; }
public int ReferenceId { get; set; }
public int WfId { get; set; }
public required string EmailAddress { get; set; }
public required string EmailSubj { get; set; }
public required string EmailBody { get; set; }
public string? ReferenceString { get; set; } = null;
public int? EntityId { get; set; } = null;
public string? WfReference { get; set; } = null;
public string? EmailAttmt1 { get; set; } = null;
public DateTime? EmailSent { get; set; } = null;
public string? Comment { get; set; } = null;
public string? AddedWho { get; set; } = "DEFAULT";
public string? ChangedWho { get; set; } = null;
public DateTime? ChangedWhen { get; set; } = null;
public DateTime? ErrorTimestamp { get; set; } = null;
public string? ErrorMsg { get; set; } = null;
}
}

View File

@@ -0,0 +1,24 @@
namespace DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
public record EmailOutDto(
int Id,
int ReminderTypeId,
int SendingProfile,
int ReferenceId,
string? ReferenceString,
int? EntityId,
int WfId,
string? WfReference,
string EmailAddress,
string EmailSubj,
string EmailBody,
string? EmailAttmt1,
DateTime? EmailSent,
string? Comment,
string AddedWho,
DateTime? AddedWhen,
string? ChangedWho,
DateTime? ChangedWhen,
DateTime? ErrorTimestamp,
string? ErrorMsg
);

View File

@@ -0,0 +1,36 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>DigitalData.EmailProfilerDispatcher.Abstraction</PackageId>
<Authors>Digital Data GmbH</Authors>
<Company>Digital Data GmbH</Company>
<Description>This package provides the necessary abstractions and interfaces for the DigitalData.EmailProfilerDispatcher library, facilitating a clean and decoupled architecture.</Description>
<Copyright>Copyright 2024</Copyright>
<PackageIcon>icon.png</PackageIcon>
<RepositoryUrl>http://git.dd:3000/AppStd/EmailProfilerDispatcher.git</RepositoryUrl>
<PackageTags>digital data email dispatcher abstraction</PackageTags>
<Version>3.2.0</Version>
<FileVersion>3.2.0</FileVersion>
<AssemblyVersion>3.2.0</AssemblyVersion>
</PropertyGroup>
<ItemGroup>
<None Include="..\Assets\icon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DigitalData.Core.Abstractions.Security" Version="1.0.0" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Abstraction.Attributes\DigitalData.EmailProfilerDispatcher.Abstraction.Attributes.csproj" />
</ItemGroup>
</Project>

View File

@@ -2,7 +2,7 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace DigitalData.EmailProfilerDispatcher.Domain.Entities
namespace DigitalData.EmailProfilerDispatcher.Abstraction.Entities
{
[Table("TBEMLP_EMAIL_OUT")]
public class EmailOut
@@ -43,16 +43,16 @@ namespace DigitalData.EmailProfilerDispatcher.Domain.Entities
[Required]
[Column("EMAIL_ADRESS", TypeName = "varchar(1000)")]
[StringLength(1000)]
public string EmailAddress { get; set; }
public required string EmailAddress { get; set; }
[Required]
[Column("EMAIL_SUBJ", TypeName = "varchar(500)")]
[StringLength(500)]
public string EmailSubj { get; set; }
public required string EmailSubj { get; set; }
[Required]
[Column("EMAIL_BODY", TypeName = "varchar(max)")]
public string EmailBody { get; set; }
public required string EmailBody { get; set; }
[Column("EMAIL_ATTMT1", TypeName = "varchar(512)")]
[StringLength(512)]
@@ -69,13 +69,13 @@ namespace DigitalData.EmailProfilerDispatcher.Domain.Entities
[Column("ADDED_WHO", TypeName = "varchar(50)")]
[StringLength(50)]
[DefaultValue("DEFAULT")]
public string AddedWho { get; set; }
public required string AddedWho { get; set; }
[Column("ADDED_WHEN")]
[DefaultValue("getdate()")]
public DateTime? AddedWhen { get; set; }
[Column("CHANGED_WHO", TypeName = "varchar(50)")]
[Column("CHANGED_WHO", TypeName = "varchar(50)")]
[StringLength(50)]
public string? ChangedWho { get; set; }
@@ -88,5 +88,16 @@ namespace DigitalData.EmailProfilerDispatcher.Domain.Entities
[Column("ERROR_MSG", TypeName = "varchar(900)")]
[StringLength(900)]
public string? ErrorMsg { get; set; }
[Column("ATTACHMENT1_BYTES", TypeName = "varbinary(max)")]
public byte[]? Attachment1Bytes { get; set; }
[Column("ATT1_RELATED_ID")]
public long? Att1RelatedId { get; set; }
[Column("ATT1_REL_TYPE", TypeName = "varchar(20)")]
[StringLength(20)]
public string? Att1RelType { get; set; }
}
}

View File

@@ -1,11 +0,0 @@
using DigitalData.Core.Contracts.Application;
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
namespace DigitalData.EmailProfilerDispatcher.Application.Contracts
{
public interface IEmailOutService : ICRUDService<IEmailOutRepository, EmailOutCreateDto, EmailOutDto, EmailOutDto, EmailOut, int>
{
}
}

View File

@@ -1,20 +0,0 @@
using DigitalData.EmailProfilerDispatcher.Application.Contracts;
using DigitalData.EmailProfilerDispatcher.Application.Services;
using DigitalData.EmailProfilerDispatcher.Infrastructure;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace DigitalData.EmailProfilerDispatcher.Application
{
public static class DIExtensions
{
public static IServiceCollection AddDispatcher<TDbContext>(this IServiceCollection services) where TDbContext : DbContext => services
.AddDispatcherRepository<TDbContext>()
.AddAutoMapper(typeof(MappingProfile).Assembly)
.AddScoped<IEmailOutService, EmailOutService>();
public static IServiceCollection AddDispatcher(this IServiceCollection services, Action<DbContextOptionsBuilder> options) => services
.AddDbContext<DefaultMailDbContext>(options)
.AddDispatcher<DefaultMailDbContext>();
}
}

View File

@@ -1,23 +0,0 @@
namespace DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut
{
public record EmailOutCreateDto(
int ReminderTypeId,
int SendingProfile,
int ReferenceId,
string? ReferenceString,
int? EntityId,
int WfId,
string? WfReference,
string EmailAddress,
string EmailSubj,
string EmailBody,
string? EmailAttmt1,
DateTime? EmailSent,
string? Comment,
string? AddedWho, // Default value will be 'DEFAULT', made nullable
string? ChangedWho,
DateTime? ChangedWhen,
DateTime? ErrorTimestamp,
string? ErrorMsg
);
}

View File

@@ -1,25 +0,0 @@
namespace DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut
{
public record EmailOutDto(
int Id,
int ReminderTypeId,
int SendingProfile,
int ReferenceId,
string? ReferenceString,
int? EntityId,
int WfId,
string? WfReference,
string EmailAddress,
string EmailSubj,
string EmailBody,
string? EmailAttmt1,
DateTime? EmailSent,
string? Comment,
string AddedWho,
DateTime? AddedWhen,
string? ChangedWho,
DateTime? ChangedWhen,
DateTime? ErrorTimestamp,
string? ErrorMsg
);
}

View File

@@ -1,35 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.19" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.19" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Domain\DigitalData.EmailProfilerDispatcher.Domain.csproj" />
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Infrastructure\DigitalData.EmailProfilerDispatcher.Infrastructure.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="DigitalData.Core.Application">
<HintPath>..\..\WebCoreModules\DigitalData.Core.Application\bin\Debug\net7.0\DigitalData.Core.Application.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.Contracts">
<HintPath>..\..\WebCoreModules\DigitalData.Core.Application\bin\Debug\net7.0\DigitalData.Core.Contracts.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.DTO">
<HintPath>..\..\WebCoreModules\DigitalData.Core.Application\bin\Debug\net7.0\DigitalData.Core.DTO.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.Infrastructure">
<HintPath>..\..\WebCoreModules\DigitalData.Core.Infrastructure\bin\Debug\net7.0\DigitalData.Core.Infrastructure.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -1,17 +0,0 @@
using AutoMapper;
using DigitalData.Core.Application;
using DigitalData.EmailProfilerDispatcher.Application.Contracts;
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
using Microsoft.Extensions.Localization;
namespace DigitalData.EmailProfilerDispatcher.Application.Services
{
public class EmailOutService : CRUDService<IEmailOutRepository, EmailOutCreateDto, EmailOutDto, EmailOutDto, EmailOut, int>, IEmailOutService
{
public EmailOutService(IEmailOutRepository repository, IStringLocalizer localizer, IMapper mapper) : base(repository, localizer, mapper)
{
}
}
}

View File

@@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

View File

@@ -1,9 +0,0 @@
using DigitalData.Core.Contracts.Infrastructure;
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
namespace DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts
{
public interface IEmailOutRepository : ICRUDRepository<EmailOut, int>
{
}
}

View File

@@ -1,17 +0,0 @@
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
using DigitalData.EmailProfilerDispatcher.Infrastructure.Repositories;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace DigitalData.EmailProfilerDispatcher.Infrastructure
{
public static class DIExtensions
{
public static IServiceCollection AddDispatcherRepository<TDbContext>(this IServiceCollection services) where TDbContext : DbContext => services
.AddScoped<IEmailOutRepository, EmailOutRepository<TDbContext>>();
public static IServiceCollection AddDispatcherRepository(this IServiceCollection services, Action<DbContextOptionsBuilder> optionsAction) => services
.AddDbContext<DefaultMailDbContext>(optionsAction)
.AddDispatcherRepository<DefaultMailDbContext>();
}
}

View File

@@ -1,39 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.19" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Domain\DigitalData.EmailProfilerDispatcher.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Reference Include="DigitalData.Core.Contracts">
<HintPath>..\..\WebCoreModules\DigitalData.Core.Infrastructure\bin\Debug\net7.0\DigitalData.Core.Contracts.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.DTO">
<HintPath>..\..\WebCoreModules\DigitalData.Core.Infrastructure\bin\Debug\net7.0\DigitalData.Core.DTO.dll</HintPath>
</Reference>
<Reference Include="DigitalData.Core.Infrastructure">
<HintPath>..\..\WebCoreModules\DigitalData.Core.Infrastructure\bin\Debug\net7.0\DigitalData.Core.Infrastructure.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -1,15 +0,0 @@
using DigitalData.Core.Infrastructure;
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
using DigitalData.EmailProfilerDispatcher.Infrastructure.Contracts;
using Microsoft.EntityFrameworkCore;
namespace DigitalData.EmailProfilerDispatcher.Infrastructure.Repositories
{
public class EmailOutRepository<TDbContext> : CRUDRepository<EmailOut, int, TDbContext>, IEmailOutRepository
where TDbContext : DbContext
{
public EmailOutRepository(TDbContext dbContext) : base(dbContext)
{
}
}
}

View File

@@ -5,11 +5,20 @@ VisualStudioVersion = 17.9.34622.214
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher.API", "DigitalData.EmailProfilerDispatcher.API\DigitalData.EmailProfilerDispatcher.API.csproj", "{352BEA44-4D3E-4D22-B1B3-B3E06A928396}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher.Domain", "DigitalData.EmailProfilerDispatcher.Domain\DigitalData.EmailProfilerDispatcher.Domain.csproj", "{2F650B4D-65F4-4F91-89C0-803790612C4E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EmailProfilerDispatcher.Tests", "EmailProfilerDispatcher.Tests\EmailProfilerDispatcher.Tests.csproj", "{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher.Application", "DigitalData.EmailProfilerDispatcher.Application\DigitalData.EmailProfilerDispatcher.Application.csproj", "{4C42937A-944D-4AAB-A835-F7EEC2C8872F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher.Abstraction", "DigitalData.EmailProfilerDispatcher.Abstraction\DigitalData.EmailProfilerDispatcher.Abstraction.csproj", "{0647F6B7-BF49-4B1F-83E4-7C843A7F9775}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher.Infrastructure", "DigitalData.EmailProfilerDispatcher.Infrastructure\DigitalData.EmailProfilerDispatcher.Infrastructure.csproj", "{F02B6F5B-FB2F-4E20-996D-BE99E9768039}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DigitalData.EmailProfilerDispatcher", "DigitalData.EmailProfilerDispatcher\DigitalData.EmailProfilerDispatcher.csproj", "{DF202B1D-6C6F-4354-9B73-20F03486D020}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Assest", "Assest", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
ProjectSection(SolutionItems) = preProject
Assets\icon.png = Assets\icon.png
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DigitalData.EmailProfilerDispatcher.Abstraction.Attributes", "DigitalData.EmailProfilerDispatcher.Abstraction.Attributes\DigitalData.EmailProfilerDispatcher.Abstraction.Attributes.csproj", "{16785881-75BA-4721-9A0C-B469FAA95D95}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -21,22 +30,29 @@ Global
{352BEA44-4D3E-4D22-B1B3-B3E06A928396}.Debug|Any CPU.Build.0 = Debug|Any CPU
{352BEA44-4D3E-4D22-B1B3-B3E06A928396}.Release|Any CPU.ActiveCfg = Release|Any CPU
{352BEA44-4D3E-4D22-B1B3-B3E06A928396}.Release|Any CPU.Build.0 = Release|Any CPU
{2F650B4D-65F4-4F91-89C0-803790612C4E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F650B4D-65F4-4F91-89C0-803790612C4E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F650B4D-65F4-4F91-89C0-803790612C4E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F650B4D-65F4-4F91-89C0-803790612C4E}.Release|Any CPU.Build.0 = Release|Any CPU
{4C42937A-944D-4AAB-A835-F7EEC2C8872F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4C42937A-944D-4AAB-A835-F7EEC2C8872F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4C42937A-944D-4AAB-A835-F7EEC2C8872F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4C42937A-944D-4AAB-A835-F7EEC2C8872F}.Release|Any CPU.Build.0 = Release|Any CPU
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F02B6F5B-FB2F-4E20-996D-BE99E9768039}.Release|Any CPU.Build.0 = Release|Any CPU
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C55114DF-F7C9-47A6-AF36-99F6C8079DE2}.Release|Any CPU.Build.0 = Release|Any CPU
{0647F6B7-BF49-4B1F-83E4-7C843A7F9775}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{0647F6B7-BF49-4B1F-83E4-7C843A7F9775}.Debug|Any CPU.Build.0 = Release|Any CPU
{0647F6B7-BF49-4B1F-83E4-7C843A7F9775}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0647F6B7-BF49-4B1F-83E4-7C843A7F9775}.Release|Any CPU.Build.0 = Release|Any CPU
{DF202B1D-6C6F-4354-9B73-20F03486D020}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{DF202B1D-6C6F-4354-9B73-20F03486D020}.Debug|Any CPU.Build.0 = Release|Any CPU
{DF202B1D-6C6F-4354-9B73-20F03486D020}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DF202B1D-6C6F-4354-9B73-20F03486D020}.Release|Any CPU.Build.0 = Release|Any CPU
{16785881-75BA-4721-9A0C-B469FAA95D95}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{16785881-75BA-4721-9A0C-B469FAA95D95}.Debug|Any CPU.Build.0 = Release|Any CPU
{16785881-75BA-4721-9A0C-B469FAA95D95}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16785881-75BA-4721-9A0C-B469FAA95D95}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{02EA681E-C7D8-13C7-8484-4AC65E1B71E8} = {8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CB0B8122-D532-4A7F-87CC-760B959A433C}
EndGlobalSection

View File

@@ -0,0 +1,21 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using DigitalData.EmailProfilerDispatcher.Repositories;
using DigitalData.EmailProfilerDispatcher.Abstraction.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
namespace DigitalData.EmailProfilerDispatcher
{
public static class DIExtensions
{
public static IServiceCollection AddDispatcher<TDbContext>(this IServiceCollection services) where TDbContext : DbContext, IMailDbContext
=> services
.AddScoped<IEmailOutRepository, EmailOutRepository<TDbContext>>()
.AddAutoMapper(typeof(MappingProfile).Assembly)
.AddScoped<IEmailOutService, EmailOutService>();
public static IServiceCollection AddDispatcher<TResource>(this IServiceCollection services, Action<DbContextOptionsBuilder> options) => services
.AddDbContext<DefaultMailDbContext>(options)
.AddDispatcher<DefaultMailDbContext>();
}
}

View File

@@ -1,9 +1,9 @@
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
using Microsoft.EntityFrameworkCore;
namespace DigitalData.EmailProfilerDispatcher.Infrastructure
namespace DigitalData.EmailProfilerDispatcher
{
public class DefaultMailDbContext : DbContext
public class DefaultMailDbContext : DbContext, IMailDbContext
{
public DbSet<EmailOut> EMailOuts { get; set; }

View File

@@ -0,0 +1,56 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net7.0;net8.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<PackageId>DigitalData.EmailProfilerDispatcher</PackageId>
<Company>Digital Data GmbH</Company>
<Copyright>Copyright 2024</Copyright>
<PackageIcon>icon.png</PackageIcon>
<PackageTags>digital data email dispatcher</PackageTags>
<Description>DigitalData.EmailProfilerDispatcher enables adding data to the Email Profiler's SQL tables for systematic and batch email dispatching. It also supports dynamic and automatic template filling using attributes, allowing object property values to populate email templates.</Description>
<Authors>Digital Data GmbH</Authors>
<RepositoryUrl>http://git.dd:3000/AppStd/EmailProfilerDispatcher.git</RepositoryUrl>
<Version>3.1.1</Version>
<AssemblyVersion>3.1.1</AssemblyVersion>
<FileVersion>3.1.1</FileVersion>
</PropertyGroup>
<ItemGroup>
<None Include="..\Assets\icon.png">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="DigitalData.Core.Application" Version="3.3.4" />
<PackageReference Include="DigitalData.Core.Infrastructure" Version="2.1.1" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.19" />
<PackageReference Include="Microsoft.Extensions.Localization.Abstractions" Version="7.0.19" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.20" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.20" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.15" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.15" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.Abstraction\DigitalData.EmailProfilerDispatcher.Abstraction.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
using Microsoft.EntityFrameworkCore;
namespace DigitalData.EmailProfilerDispatcher
{
public interface IMailDbContext
{
public DbSet<EmailOut> EMailOuts { get; }
}
}

View File

@@ -1,8 +1,8 @@
using AutoMapper;
using DigitalData.EmailProfilerDispatcher.Application.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Domain.Entities;
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
namespace DigitalData.EmailProfilerDispatcher.Application
namespace DigitalData.EmailProfilerDispatcher
{
public class MappingProfile : Profile
{

View File

@@ -0,0 +1,16 @@
using DigitalData.Core.Abstraction.Application.Repository;
using DigitalData.Core.Infrastructure;
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
using Microsoft.EntityFrameworkCore;
namespace DigitalData.EmailProfilerDispatcher.Repositories;
[Obsolete("Use IRepository")]
public class EmailOutRepository<TDbContext> : CRUDRepository<EmailOut, int, TDbContext>, IEmailOutRepository
where TDbContext : DbContext, IMailDbContext
{
public EmailOutRepository(TDbContext dbContext) : base(dbContext, dbContext.EMailOuts)
{
}
}

View File

@@ -0,0 +1,31 @@
using AutoMapper;
using DigitalData.Core.Application;
using DigitalData.Core.Abstraction.Application.DTO;
using DigitalData.EmailProfilerDispatcher.Abstraction.Contracts;
using DigitalData.EmailProfilerDispatcher.Abstraction.DTOs.EmailOut;
using DigitalData.EmailProfilerDispatcher.Abstraction.Entities;
namespace DigitalData.EmailProfilerDispatcher.Abstraction.Services;
public class EmailOutService : CRUDService<IEmailOutRepository, EmailOutCreateDto, EmailOutDto, EmailOut, int>, IEmailOutService
{
public EmailOutService(IEmailOutRepository repository, IMapper mapper) : base(repository, mapper)
{
}
public async Task<DataResult<int>> CreateWithTemplateAsync(EmailOutCreateDto createDto, params object[] models)
{
createDto.EmailSubj = createDto.EmailSubj.FillTemplate(models);
createDto.EmailBody = createDto.EmailBody.FillTemplate(models);
return await base.CreateAsync(createDto).ThenAsync(email => Result.Success(email.Id), (msg, ntc) => Result.Fail<int>().Message(msg).Notice(ntc));
}
public async Task<DataResult<int>> CreateWithTemplateAsync(EmailOutCreateDto createDto, Dictionary<string, string> placeholders, params object[] models)
{
createDto.EmailSubj = createDto.EmailSubj.FillTemplate(placeholders);
createDto.EmailBody = createDto.EmailBody.FillTemplate(placeholders);
return await CreateWithTemplateAsync(createDto, models: models);
}
}

View File

@@ -0,0 +1,37 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using System.Reflection;
namespace DigitalData.EmailProfilerDispatcher
{
public static class TemplateExtensions
{
public static string FillTemplate(this string template, params object[] models)
{
foreach (var model in models)
{
var properties = model.GetType().GetProperties();
foreach (var property in properties)
{
var attribute = property.GetCustomAttribute<TemplatePlaceholderAttribute>();
if (attribute != null)
{
var value = property.GetValue(model)?.ToString();
template = template.Replace(attribute.Placeholder, value);
}
}
}
return template;
}
public static string FillTemplate(this string template, Dictionary<string, string> placeholders)
{
foreach (var ph in placeholders)
template = template.Replace(ph.Key, ph.Value);
return template;
}
}
}

View File

@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="3.2.0" />
<PackageReference Include="DigitalData.Core.Application" Version="3.3.4" />
<PackageReference Include="DigitalData.Core.Abstraction.Application" Version="1.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.1" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit.Analyzers" Version="3.6.1" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DigitalData.EmailProfilerDispatcher.API\DigitalData.EmailProfilerDispatcher.API.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,66 @@
using DigitalData.EmailProfilerDispatcher.Abstraction.Attributes;
using DigitalData.EmailProfilerDispatcher;
namespace EmailProfilerDispatcher.Tests
{
[TestFixture]
public class FillTemplateTests
{
[SetUp]
public void Setup()
{
}
[Test]
public void FillTemplate_ShouldReplacePlaceholdersWithPropertyValues()
{
// Arrange
var template = @"Guten Tag [NAME_RECEIVER],<br />
<br />
hiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'[DOCUMENT_TITLE]'</I></B>.<br />
Wenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!
<br />
Mit freundlichen Grüßen<br />
<br />
[NAME_PORTAL]";
var mailData1 = new MailData1();
var mailData2 = new MailData2();
Dictionary<string, string> placeholders = new()
{
{ @"[NAME_PORTAL]", "DokumentenPortal" }
};
var expectedOutput = @"Guten Tag Tom,<br />
<br />
hiermit bestätigen wir Ihnen die erfolgreiche Signatur für den Vorgang <B><I>'Vertragsdokument'</I></B>.<br />
Wenn alle Vertragspartner unterzeichnet haben, erhalten Sie ebenfalls per email ein unterschriebenes Exemplar mit dem Signierungszertifikat!
<br />
Mit freundlichen Grüßen<br />
<br />
DokumentenPortal";
// Act
var result = template
.FillTemplate(placeholders)
.FillTemplate(template, mailData1, mailData2);
// Assert
Assert.That(result, Is.EqualTo(expectedOutput));
}
public class Resource {}
public class MailData1
{
[TemplatePlaceholder("[NAME_RECEIVER]")]
public string NameReceiver { get; set; } = "Tom";
}
public record MailData2
{
[TemplatePlaceholder("[DOCUMENT_TITLE]")]
public string DocumentTitle { get; set; } = "Vertragsdokument";
}
}
}