Indiko.Blocks.Messaging.Abstractions
2.1.1
dotnet add package Indiko.Blocks.Messaging.Abstractions --version 2.1.1
NuGet\Install-Package Indiko.Blocks.Messaging.Abstractions -Version 2.1.1
<PackageReference Include="Indiko.Blocks.Messaging.Abstractions" Version="2.1.1" />
<PackageVersion Include="Indiko.Blocks.Messaging.Abstractions" Version="2.1.1" />
<PackageReference Include="Indiko.Blocks.Messaging.Abstractions" />
paket add Indiko.Blocks.Messaging.Abstractions --version 2.1.1
#r "nuget: Indiko.Blocks.Messaging.Abstractions, 2.1.1"
#:package Indiko.Blocks.Messaging.Abstractions@2.1.1
#addin nuget:?package=Indiko.Blocks.Messaging.Abstractions&version=2.1.1
#tool nuget:?package=Indiko.Blocks.Messaging.Abstractions&version=2.1.1
Indiko.Blocks.Messaging.Abstractions
Core abstractions for messaging services including email, SMS, and push notifications with template engine support.
Overview
This package provides fundamental contracts for implementing messaging systems across different channels (email, SMS, push notifications) with built-in template processing and placeholder replacement.
Features
- IMessageSender<T>: Generic message sender interface
- IMessage: Message contract
- ISendResult: Send result abstraction
- Template Engine: Built-in template processing
- Placeholder Replacement: Dynamic content replacement in templates
- Multi-Channel: Support for email, SMS, push notifications
- Async/Await: Full asynchronous support
Installation
dotnet add package Indiko.Blocks.Messaging.Abstractions
Key Interfaces
IMessageSender<T>
Generic interface for sending messages.
public interface IMessageSender<T> where T : ISendResult
{
Task<T> SendAsync(IMessage message, CancellationToken cancellationToken = default);
}
IMessage
Base interface for all message types.
public interface IMessage
{
string Subject { get; }
string Body { get; }
Dictionary<string, string> Metadata { get; }
}
ISendResult
Result of a send operation.
public interface ISendResult
{
bool Success { get; }
string MessageId { get; }
string ErrorMessage { get; }
}
Template Engine
ITemplateEngine
Process templates with placeholder replacement.
public interface ITemplateEngine
{
string ProcessTemplate(string template, Dictionary<string, string> placeholders);
Task<string> ProcessTemplateAsync(string templatePath, Dictionary<string, string> placeholders);
}
Usage Example
public class EmailService
{
private readonly ITemplateEngine _templateEngine;
private readonly IMessageSender<EmailSendResult> _emailSender;
public async Task SendWelcomeEmailAsync(string email, string firstName)
{
// Load template
var template = await File.ReadAllTextAsync("Templates/WelcomeEmail.html");
// Define placeholders
var placeholders = new Dictionary<string, string>
{
{ "FirstName", firstName },
{ "Year", DateTime.Now.Year.ToString() },
{ "SupportEmail", "support@example.com" }
};
// Process template
var body = _templateEngine.ProcessTemplate(template, placeholders);
// Create message
var message = new EmailMessage
{
To = email,
Subject = $"Welcome, {firstName}!",
Body = body,
IsHtml = true
};
// Send
var result = await _emailSender.SendAsync(message);
if (!result.Success)
{
_logger.LogError($"Failed to send email: {result.ErrorMessage}");
}
}
}
Placeholder Replacement
IPlaceholderReplacer
Replace placeholders in text.
public interface IPlaceholderReplacer
{
string Replace(string text, Dictionary<string, string> placeholders);
}
Placeholder Syntax
Supports multiple placeholder formats:
{{FirstName}} - Double curly braces
{FirstName} - Single curly braces
[FirstName] - Square brackets
$FirstName$ - Dollar signs
%FirstName% - Percent signs
Example Templates
Email Template (HTML):
<!DOCTYPE html>
<html>
<head>
<title>Welcome Email</title>
</head>
<body>
<h1>Welcome, {{FirstName}}!</h1>
<p>Thank you for joining us, {{FirstName}} {{LastName}}.</p>
<p>Your account was created on {{SignupDate}}.</p>
<p>If you have questions, contact us at {{SupportEmail}}.</p>
<p>© {{Year}} {{CompanyName}}. All rights reserved.</p>
</body>
</html>
SMS Template:
Hi {{FirstName}}, welcome to {{CompanyName}}!
Your verification code is: {{VerificationCode}}
This code expires in {{ExpiryMinutes}} minutes.
Push Notification Template:
{
"title": "New Message from {{SenderName}}",
"body": "{{MessagePreview}}",
"data": {
"messageId": "{{MessageId}}",
"senderId": "{{SenderId}}"
}
}
Message Types
Email Message
public class EmailMessage : IMessage
{
public string To { get; set; }
public string From { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public bool IsHtml { get; set; }
public List<string> Cc { get; set; }
public List<string> Bcc { get; set; }
public List<Attachment> Attachments { get; set; }
public Dictionary<string, string> Metadata { get; set; }
}
SMS Message
public class SmsMessage : IMessage
{
public string To { get; set; }
public string From { get; set; }
public string Subject { get; set; } = string.Empty;
public string Body { get; set; }
public Dictionary<string, string> Metadata { get; set; }
}
Push Notification Message
public class PushNotificationMessage : IMessage
{
public string[] DeviceTokens { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string Title { get; set; }
public Dictionary<string, string> Data { get; set; }
public Dictionary<string, string> Metadata { get; set; }
}
Send Results
Email Send Result
public class EmailSendResult : ISendResult
{
public bool Success { get; set; }
public string MessageId { get; set; }
public string ErrorMessage { get; set; }
public DateTime SentAt { get; set; }
public List<string> FailedRecipients { get; set; }
}
SMS Send Result
public class SmsSendResult : ISendResult
{
public bool Success { get; set; }
public string MessageId { get; set; }
public string ErrorMessage { get; set; }
public decimal Cost { get; set; }
public int SegmentCount { get; set; }
}
Template Processing Examples
Simple Text Replacement
var template = "Hello {{Name}}, your order #{{OrderId}} has been shipped!";
var placeholders = new Dictionary<string, string>
{
{ "Name", "John Doe" },
{ "OrderId", "12345" }
};
var result = _templateEngine.ProcessTemplate(template, placeholders);
// Result: "Hello John Doe, your order #12345 has been shipped!"
Conditional Content
var template = @"
Dear {{CustomerName}},
{{#IsPremium}}
As a premium member, you get free shipping!
{{/IsPremium}}
{{^IsPremium}}
Upgrade to premium for free shipping.
{{/IsPremium}}
Best regards,
{{CompanyName}}
";
var placeholders = new Dictionary<string, string>
{
{ "CustomerName", "Jane Smith" },
{ "IsPremium", "true" },
{ "CompanyName", "Acme Corp" }
};
Lists and Loops
var template = @"
Order Summary for {{CustomerName}}:
{{#Items}}
- {{Name}}: ${{Price}} x {{Quantity}} = ${{Total}}
{{/Items}}
Total: ${{OrderTotal}}
";
Best Practices
- Template Storage: Store templates in files or database
- Validation: Validate placeholders before sending
- Error Handling: Always check ISendResult.Success
- Logging: Log all send operations
- Rate Limiting: Implement rate limiting for bulk sends
- Retries: Implement retry logic for transient failures
- Testing: Test templates with various placeholder values
Configuration
MessagingOptions
public class MessagingOptions
{
public bool Enabled { get; set; } = true;
public string TemplateDirectory { get; set; } = "Templates";
public string DefaultFrom { get; set; }
public int MaxRetries { get; set; } = 3;
public TimeSpan RetryDelay { get; set; } = TimeSpan.FromSeconds(5);
}
Configuration Example
{
"MessagingOptions": {
"Enabled": true,
"TemplateDirectory": "EmailTemplates",
"DefaultFrom": "noreply@example.com",
"MaxRetries": 3,
"RetryDelay": "00:00:05"
}
}
Testing
Mock Message Sender
public class MockMessageSender : IMessageSender<EmailSendResult>
{
public Task<EmailSendResult> SendAsync(
IMessage message,
CancellationToken cancellationToken = default)
{
// For testing - don't actually send
return Task.FromResult(new EmailSendResult
{
Success = true,
MessageId = Guid.NewGuid().ToString(),
SentAt = DateTime.UtcNow
});
}
}
Target Framework
- .NET 10
Dependencies
Indiko.Blocks.Common.Abstractions
License
See LICENSE file in the repository root.
Related Packages
Indiko.Blocks.Messaging.EMail- Email implementationIndiko.Blocks.Messaging.PushNotification- Push notification implementationIndiko.Blocks.Messaging.AzureNotificationHub- Azure Notification Hub implementation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- CommunityToolkit.Diagnostics (>= 8.4.0)
- Indiko.Blocks.Common.Abstractions (>= 2.1.1)
- Microsoft.Extensions.Options (>= 10.0.0)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Indiko.Blocks.Messaging.Abstractions:
| Package | Downloads |
|---|---|
|
Indiko.Blocks.Messaging.EMail
Building Blocks Messaging EMail |
|
|
Indiko.Blocks.Messaging.AzureNotificationHub
Building Blocks Messaging Azure Notification Hub |
|
|
Indiko.Blocks.Messaging.PushNotification
Building Blocks Messaging Push Notification for Google FCN and Apple APNS |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.1.1 | 40 | 12/2/2025 |
| 2.1.0 | 37 | 12/2/2025 |
| 2.0.0 | 286 | 9/17/2025 |
| 1.7.23 | 341 | 9/8/2025 |
| 1.7.22 | 190 | 9/8/2025 |
| 1.7.21 | 202 | 8/14/2025 |
| 1.7.20 | 226 | 6/23/2025 |
| 1.7.19 | 198 | 6/3/2025 |
| 1.7.18 | 217 | 5/29/2025 |
| 1.7.17 | 206 | 5/26/2025 |
| 1.7.15 | 154 | 4/12/2025 |
| 1.7.14 | 179 | 4/11/2025 |
| 1.7.13 | 184 | 3/29/2025 |
| 1.7.12 | 199 | 3/28/2025 |
| 1.7.11 | 208 | 3/28/2025 |
| 1.7.10 | 199 | 3/28/2025 |
| 1.7.9 | 186 | 3/28/2025 |
| 1.7.8 | 197 | 3/28/2025 |
| 1.7.5 | 219 | 3/17/2025 |
| 1.7.4 | 195 | 3/16/2025 |
| 1.7.3 | 201 | 3/16/2025 |
| 1.7.2 | 200 | 3/16/2025 |
| 1.7.1 | 263 | 3/11/2025 |
| 1.6.8 | 225 | 3/11/2025 |
| 1.6.7 | 275 | 3/4/2025 |
| 1.6.6 | 152 | 2/26/2025 |
| 1.6.5 | 179 | 2/20/2025 |
| 1.6.4 | 174 | 2/20/2025 |
| 1.6.3 | 179 | 2/5/2025 |
| 1.6.2 | 162 | 1/24/2025 |
| 1.6.1 | 155 | 1/24/2025 |
| 1.6.0 | 147 | 1/16/2025 |
| 1.5.2 | 163 | 1/16/2025 |
| 1.5.1 | 213 | 11/3/2024 |
| 1.5.0 | 183 | 10/26/2024 |
| 1.3.2 | 186 | 10/24/2024 |
| 1.3.0 | 184 | 10/10/2024 |
| 1.2.5 | 193 | 10/9/2024 |
| 1.2.4 | 193 | 10/8/2024 |
| 1.2.1 | 183 | 10/3/2024 |
| 1.2.0 | 173 | 9/29/2024 |
| 1.1.1 | 183 | 9/23/2024 |
| 1.1.0 | 201 | 9/18/2024 |
| 1.0.33 | 208 | 9/15/2024 |
| 1.0.28 | 193 | 8/28/2024 |
| 1.0.27 | 207 | 8/24/2024 |
| 1.0.26 | 198 | 7/7/2024 |
| 1.0.25 | 153 | 7/6/2024 |
| 1.0.24 | 162 | 6/25/2024 |
| 1.0.23 | 203 | 6/1/2024 |
| 1.0.22 | 181 | 5/14/2024 |
| 1.0.21 | 180 | 5/14/2024 |
| 1.0.20 | 204 | 4/8/2024 |
| 1.0.19 | 206 | 4/3/2024 |
| 1.0.18 | 205 | 3/23/2024 |
| 1.0.17 | 222 | 3/19/2024 |
| 1.0.16 | 198 | 3/19/2024 |
| 1.0.15 | 209 | 3/11/2024 |
| 1.0.14 | 200 | 3/10/2024 |
| 1.0.13 | 207 | 3/6/2024 |
| 1.0.12 | 213 | 3/1/2024 |
| 1.0.11 | 205 | 3/1/2024 |
| 1.0.10 | 199 | 3/1/2024 |
| 1.0.9 | 195 | 3/1/2024 |
| 1.0.8 | 197 | 2/19/2024 |
| 1.0.7 | 183 | 2/17/2024 |
| 1.0.6 | 207 | 2/17/2024 |
| 1.0.5 | 196 | 2/17/2024 |
| 1.0.4 | 203 | 2/7/2024 |
| 1.0.3 | 201 | 2/6/2024 |
| 1.0.1 | 165 | 2/6/2024 |
| 1.0.0 | 241 | 1/9/2024 |
| 1.0.0-preview99 | 227 | 12/22/2023 |
| 1.0.0-preview98 | 182 | 12/21/2023 |
| 1.0.0-preview97 | 166 | 12/21/2023 |
| 1.0.0-preview96 | 189 | 12/20/2023 |
| 1.0.0-preview95 | 153 | 12/20/2023 |
| 1.0.0-preview94 | 152 | 12/18/2023 |
| 1.0.0-preview93 | 182 | 12/13/2023 |
| 1.0.0-preview92 | 188 | 12/13/2023 |
| 1.0.0-preview91 | 184 | 12/12/2023 |
| 1.0.0-preview90 | 155 | 12/11/2023 |
| 1.0.0-preview89 | 180 | 12/11/2023 |
| 1.0.0-preview88 | 200 | 12/6/2023 |
| 1.0.0-preview87 | 187 | 12/6/2023 |
| 1.0.0-preview86 | 193 | 12/6/2023 |
| 1.0.0-preview85 | 176 | 12/6/2023 |
| 1.0.0-preview84 | 195 | 12/5/2023 |
| 1.0.0-preview83 | 198 | 12/5/2023 |
| 1.0.0-preview82 | 194 | 12/5/2023 |
| 1.0.0-preview81 | 180 | 12/4/2023 |
| 1.0.0-preview80 | 187 | 12/1/2023 |
| 1.0.0-preview77 | 177 | 12/1/2023 |
| 1.0.0-preview76 | 185 | 12/1/2023 |
| 1.0.0-preview75 | 187 | 12/1/2023 |
| 1.0.0-preview74 | 205 | 11/26/2023 |
| 1.0.0-preview73 | 185 | 11/7/2023 |
| 1.0.0-preview72 | 198 | 11/6/2023 |
| 1.0.0-preview71 | 207 | 11/3/2023 |
| 1.0.0-preview70 | 197 | 11/2/2023 |
| 1.0.0-preview69 | 182 | 11/2/2023 |
| 1.0.0-preview68 | 182 | 11/2/2023 |
| 1.0.0-preview67 | 202 | 11/2/2023 |
| 1.0.0-preview66 | 176 | 11/2/2023 |
| 1.0.0-preview65 | 194 | 11/2/2023 |
| 1.0.0-preview64 | 207 | 11/2/2023 |
| 1.0.0-preview63 | 188 | 11/2/2023 |
| 1.0.0-preview62 | 200 | 11/1/2023 |
| 1.0.0-preview61 | 180 | 11/1/2023 |
| 1.0.0-preview60 | 182 | 11/1/2023 |
| 1.0.0-preview59 | 195 | 11/1/2023 |
| 1.0.0-preview58 | 193 | 10/31/2023 |
| 1.0.0-preview57 | 182 | 10/31/2023 |
| 1.0.0-preview56 | 197 | 10/31/2023 |
| 1.0.0-preview55 | 189 | 10/31/2023 |
| 1.0.0-preview54 | 206 | 10/31/2023 |
| 1.0.0-preview53 | 183 | 10/31/2023 |
| 1.0.0-preview52 | 196 | 10/31/2023 |
| 1.0.0-preview51 | 174 | 10/31/2023 |
| 1.0.0-preview50 | 193 | 10/31/2023 |
| 1.0.0-preview48 | 174 | 10/31/2023 |
| 1.0.0-preview46 | 185 | 10/31/2023 |
| 1.0.0-preview45 | 181 | 10/31/2023 |
| 1.0.0-preview44 | 190 | 10/31/2023 |
| 1.0.0-preview43 | 181 | 10/31/2023 |
| 1.0.0-preview42 | 181 | 10/30/2023 |
| 1.0.0-preview41 | 184 | 10/30/2023 |
| 1.0.0-preview40 | 187 | 10/27/2023 |
| 1.0.0-preview39 | 171 | 10/27/2023 |
| 1.0.0-preview38 | 189 | 10/27/2023 |
| 1.0.0-preview37 | 184 | 10/27/2023 |
| 1.0.0-preview36 | 200 | 10/27/2023 |
| 1.0.0-preview35 | 179 | 10/27/2023 |
| 1.0.0-preview34 | 170 | 10/27/2023 |
| 1.0.0-preview33 | 196 | 10/26/2023 |
| 1.0.0-preview32 | 194 | 10/26/2023 |
| 1.0.0-preview31 | 191 | 10/26/2023 |
| 1.0.0-preview30 | 194 | 10/26/2023 |
| 1.0.0-preview29 | 196 | 10/26/2023 |
| 1.0.0-preview28 | 210 | 10/26/2023 |
| 1.0.0-preview27 | 187 | 10/26/2023 |
| 1.0.0-preview26 | 216 | 10/25/2023 |
| 1.0.0-preview25 | 195 | 10/23/2023 |
| 1.0.0-preview24 | 168 | 10/23/2023 |
| 1.0.0-preview23 | 163 | 10/23/2023 |
| 1.0.0-preview101 | 179 | 1/5/2024 |