IranSMS.Extensions.DependencyInjection
1.0.0
dotnet add package IranSMS.Extensions.DependencyInjection --version 1.0.0
NuGet\Install-Package IranSMS.Extensions.DependencyInjection -Version 1.0.0
<PackageReference Include="IranSMS.Extensions.DependencyInjection" Version="1.0.0" />
<PackageVersion Include="IranSMS.Extensions.DependencyInjection" Version="1.0.0" />
<PackageReference Include="IranSMS.Extensions.DependencyInjection" />
paket add IranSMS.Extensions.DependencyInjection --version 1.0.0
#r "nuget: IranSMS.Extensions.DependencyInjection, 1.0.0"
#:package IranSMS.Extensions.DependencyInjection@1.0.0
#addin nuget:?package=IranSMS.Extensions.DependencyInjection&version=1.0.0
#tool nuget:?package=IranSMS.Extensions.DependencyInjection&version=1.0.0
IranSMS
IranSMS is a provider-neutral, asynchronous .NET library for Iranian SMS gateways.
Packages
dotnet add package IranSMS --version 1.0.0
dotnet add package IranSMS.Extensions.DependencyInjection --version 1.0.0
IranSMS contains the core contracts and providers. The optional DI package adds named provider registration backed by IHttpClientFactory for .NET 8 and .NET 10 applications.
Target frameworks
Core package:
net462netstandard2.0net8.0net10.0
DI package:
net8.0net10.0
The netstandard2.0 asset is the compatibility path for many .NET Framework, .NET Core, Mono, Xamarin, and modern .NET applications. The explicit targets provide framework-specific networking behavior where it materially improves reliability.
Included providers
- Kavenegar: normal SMS and lookup/pattern
- SMS.ir: bulk and verify
- IPPanel: normal SMS and pattern
- MeliPayamak: normal SMS and BaseServiceNumber pattern
- Ghasedak: bulk and NewOTP
- Bale: phone-based messenger notification; not carrier SMS
Direct usage
using IranSMS;
using IranSMS.Models;
using IranSMS.Providers.SmsIr;
using var provider = new SmsIrSmsProvider(new SmsIrOptions
{
ApiKey = configuration["Sms:ApiKey"]
?? throw new InvalidOperationException("Sms:ApiKey is required."),
LineNumber = configuration["Sms:LineNumber"]
?? throw new InvalidOperationException("Sms:LineNumber is required.")
});
var client = new SmsClient(provider);
SmsSendResult result = await client.SendPatternAsync(
new[] { "09120000000" },
"123456",
new[] { new SmsPatternParameter("Code", "481927") },
cancellationToken);
if (result.SubmissionStatus == SmsSubmissionStatus.Rejected)
{
SmsGatewayError? error = result.Error;
logger.LogWarning(
"SMS submission rejected. Provider={Provider}, Status={Status}, Stage={Stage}, MayBeAccepted={MayBeAccepted}, RetrySafety={RetrySafety}, RetryAfter={RetryAfter}",
result.ProviderId,
error?.HttpStatusCode,
error?.FailureStage,
error?.RequestMayHaveBeenAccepted,
error?.RetrySafety,
error?.RetryAfter);
}
IsSuccess means every recipient was accepted by the gateway. It does not prove handset delivery. Delivery receipts require a provider-specific status query or webhook integration.
Dependency injection
using Microsoft.Extensions.DependencyInjection;
using IranSMS.Extensions.DependencyInjection;
services.AddIranSMS(builder => builder
.AddSmsIr("primary", options =>
{
options.ApiKey = configuration["Sms:SmsIr:ApiKey"]!;
options.LineNumber = configuration["Sms:SmsIr:LineNumber"]!;
})
.AddKavenegar("fallback", options =>
{
options.ApiKey = configuration["Sms:Kavenegar:ApiKey"]!;
options.SenderNumber = configuration["Sms:Kavenegar:Sender"]!;
}));
ISmsProviderResolver resolver = serviceProvider.GetRequiredService<ISmsProviderResolver>();
SmsClient client = resolver.CreateClient("primary");
The DI package uses a bounded SocketsHttpHandler, disables redirects and cookies, rotates pooled connections, and removes the default IHttpClientFactory request loggers. Kavenegar places its API key in the URL path. This removal does not disable runtime System.Net.Http activities or custom HTTP instrumentation; hosts must filter or redact full outbound URLs before export.
Networking and memory guarantees
- Fully asynchronous provider APIs with caller
CancellationTokensupport. - No
.Result,.Wait(),async void, or per-requestHttpClientconstruction. - Separate
SmsRequestTimeoutExceptionfor internal timeout; caller cancellation remainsOperationCanceledException. ResponseHeadersReadplus a configurable hard response limit.- Bounded JSON and URL-encoded request serialization based on final byte count.
- Per-provider concurrency gate.
- HTTPS required by default; plain HTTP must be enabled explicitly for a controlled legacy endpoint.
- Injected
HttpClientownership remains with the caller. - Provider options are snapshotted when the provider is constructed.
- Bounded diagnostic messages, references, codes, recipients, and provider request IDs.
- No automatic send retry. Failures expose
FailureStage,RequestMayHaveBeenAccepted, andRetrySafety; HTTP 5xx, transport loss, timeout, and unreadable responses are treated conservatively because blind retry can duplicate messages.
Legacy pattern compatibility
pattern:123456
Code:481927
Name:Pedram
SmsSendResult result = await client.SendLegacyMessageAsync(
new[] { "09120000000" },
legacyMessage,
cancellationToken);
Build and release gates
./pack-client.sh
or on Windows:
./Build-NuGet.cmd
The build scripts use the SDK version pinned in global.json. When that SDK is not installed, the bootstrap scripts install it into the repository-local .dotnet/ directory through the official dotnet-install script.
The pipeline performs:
- recommended .NET analyzers with warnings as errors
- source API contract verification and compiled package validation
- full-SHA GitHub Action pin verification
- preview-aware package-lock validation; lock files are mandatory for stable releases
- static secret and async-pattern checks
- builds on Windows and Linux
- tests on .NET 8 and .NET 10
- an executable .NET Framework 4.6.2 smoke test on Windows
- provider response fixture tests
- package validation and NuGet audit
- package-content validation
- installation and execution from a local NuGet feed
- separate manual live-provider contract tests
- scheduled load and managed-memory smoke tests
Publishing uses NuGet Trusted Publishing through GitHub OIDC. A permanent NuGet API key is not stored in the repository. Third-party workflow actions are pinned to reviewed full commit SHAs. Official 1.x packages remain unsigned to preserve a stable assembly identity.
License and attribution
This project is distributed under the Apache License 2.0. See LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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
- IranSMS (>= 1.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.9)
- Microsoft.Extensions.Http (>= 10.0.9)
- Microsoft.Extensions.Options (>= 10.0.9)
- Newtonsoft.Json (>= 13.0.4)
-
net8.0
- IranSMS (>= 1.0.0)
- Microsoft.Extensions.DependencyInjection (>= 10.0.9)
- Microsoft.Extensions.Http (>= 10.0.9)
- Microsoft.Extensions.Options (>= 10.0.9)
- Newtonsoft.Json (>= 13.0.4)
- System.Diagnostics.DiagnosticSource (>= 10.0.9)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 106 | 8/24/2026 |
Initial public preview of the IranSMS dependency-injection integration.