Skip to main content

integrate-dapr-services

Run ABP's own abstractions (client proxies, distributed event bus, distributed lock) over a Dapr sidecar with little or no code change. USE FOR: adding the Volo.Abp.Dapr modules, invoking services through Dapr service invocation, backing IDistributedEventBus with Dapr pub/sub, using Dapr for distributed locking, securing receive endpoints with the App API token; also when you see Dapr app-ids, sidecars, or [Topic] attributes in an ABP project. DO NOT USE FOR: deciding sync-vs-async or the outbox/inbox and idempotency design itself (use design-module-and-service-communication); plain HTTP client proxies without Dapr (use consume-remote-services); non-Dapr distributed locking/caching providers (use the distributed-caching-and-locking skill).

설치로 이동

소스 정보

저장소
abpframework/abp-skills
최근 소스 활동
2026년 7월 20일 03:24
감지된 SKILL.md 언어
영어
스타
18
포크
0

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
integrate-dapr-services
description
Run ABP's own abstractions (client proxies, distributed event bus, distributed lock) over a Dapr sidecar with little or no code change. USE FOR: adding the Volo.Abp.Dapr modules, invoking services through Dapr service invocation, backing IDistributedEventBus with Dapr pub/sub, using Dapr for distributed locking, securing receive endpoints with the App API token; also when you see Dapr app-ids, sidecars, or [Topic] attributes in an ABP project. DO NOT USE FOR: deciding sync-vs-async or the outbox/inbox and idempotency design itself (use design-module-and-service-communication); plain HTTP client proxies without Dapr (use consume-remote-services); non-Dapr distributed locking/caching providers (use the distributed-caching-and-locking skill).
license
MIT
# ABP Dapr Integration [Dapr](https://dapr.io/) decouples common microservice concerns (service invocation, pub/sub, locking) into a sidecar runtime. ABP ships integration packages so its own abstractions (client proxies, `IDistributedEventBus`, `IAbpDistributedLock`) run *over* Dapr with little or no code change. ABP and Dapr are complementary — ABP gives the opinionated architecture, Dapr the runtime plumbing. ## When to Use - Adding the `Volo.Abp.Dapr` modules to an ABP solution. - Routing ABP client proxies through Dapr service invocation. - Backing the distributed event bus with Dapr pub/sub (publish and/or receive). - Using Dapr's building block for `IAbpDistributedLock`. - Securing Dapr receive endpoints with the App API token. - Working in a project that already uses Dapr app-ids, sidecars, or `[Topic]` attributes. ## When Not to Use - **Deciding whether to communicate sync vs async**, or designing the outbox/inbox and idempotency — use the **design-module-and-service-communication** skill (this skill is the Dapr *transport*, not the design). - **Plain HTTP client proxies without Dapr** — use the **consume-remote-services** skill. - **Non-Dapr distributed locking / caching providers** — use the **distributed-caching-and-locking** skill. ## How it works ### Packages Add only what you need; each depends on the core `Volo.Abp.Dapr`: - **`Volo.Abp.Dapr`** — core package (`AbpDaprModule`). Provides `AbpDaprOptions` and `IAbpDaprClientFactory`. Everything else references it. - **`Volo.Abp.Http.Client.Dapr`** (`AbpHttpClientDaprModule`) — routes ABP's dynamic/static C# client proxies through Dapr service invocation. - **`Volo.Abp.EventBus.Dapr`** (`AbpEventBusDaprModule`) — distributed event bus over Dapr pub/sub. **Publish only** (can send, can't receive). - **`Volo.Abp.AspNetCore.Mvc.Dapr.EventBus`** (`AbpAspNetCoreMvcDaprEventBusModule`) — adds the subscription endpoints so an ASP.NET Core app can also **receive** events. Already references `Volo.Abp.EventBus.Dapr`, so install this one to send *and* receive. - **`Volo.Abp.DistributedLocking.Dapr`** (`AbpDistributedLockingDaprModule`) — backs `IAbpDistributedLock` with Dapr's lock building block. Install a package with `abp add-package Volo.Abp.Dapr` (etc.), or manually add the NuGet reference plus `[DependsOn(typeof(AbpDaprModule))]` on your module class. ### Core options and client factory `AbpDaprModule` binds the `Dapr` section of configuration into `AbpDaprOptions`. All settings are optional — you usually configure nothing: ```csharp Configure<AbpDaprOptions>(options => { // HttpEndpoint, GrpcEndpoint, DaprApiToken, AppApiToken }); ``` ```json "Dapr": { "HttpEndpoint": "http://localhost:3500/" } ``` `DaprApiToken` defaults from the `DAPR_API_TOKEN` env var and `AppApiToken` from `APP_API_TOKEN` — both set by Dapr at runtime, so they're normally auto-filled. Use `IAbpDaprClientFactory` to build `DaprClient` / `HttpClient` objects that already honor these options: ```csharp public class MyService : ITransientDependency { private readonly IAbpDaprClientFactory _daprClientFactory; public MyService(IAbpDaprClientFactory daprClientFactory) => _daprClientFactory = daprClientFactory; public async Task DoItAsync() { DaprClient daprClient = await _daprClientFactory.CreateAsync(); HttpClient httpClient = await _daprClientFactory.CreateHttpClientAsync("target-app-id"); } } ``` ### Service invocation (client proxies over Dapr) With `Volo.Abp.Http.Client.Dapr` installed, point ABP's remote service base URL at the target **Dapr app-id** instead of a host: ```json { "RemoteServices": { "Default": { "BaseUrl": "http://dapr-httpapi/" } } } ``` Here `dapr-httpapi` is the server app's Dapr application id. The remote service name (`Default`) must match the name used in `AddHttpClientProxies` / `AddStaticHttpClientProxies`. After that, your existing client-proxy calls automatically go through Dapr's service invocation building block — no call-site changes. ### Distributed event bus over Dapr pub/sub Once the pub/sub packages are installed, use the event bus exactly as documented for [distributed events](https://github.com/abpframework/abp/blob/rel-10.5/docs/en/framework/infrastructure/event-bus/distributed/index.md) — publish with `IDistributedEventBus.PublishAsync`, subscribe by implementing `IDistributedEventHandler<TEvent>`. ABP auto-registers your handlers with Dapr; no application code change to switch to Dapr as the provider. Configure the pub/sub component name (defaults to `pubsub`): ```csharp Configure<AbpDaprEventBusOptions>(options => { options.PubSubName = "pubsub"; }); ``` ABP exposes two endpoints Dapr uses: - `dapr/subscribe` — Dapr fetches the subscription list here (ABP fills it from your handlers and any `[Topic]` controller actions). - `api/abp/dapr/event` — the unified receive endpoint; ABP dispatches to the right handler by topic. > ABP calls `MapSubscribeHandler` internally — don't call it yourself. Add `app.UseCloudEvents()` if you want CloudEvents support. Two Dapr-specific caveats: - **Dynamic (string-based) events are not supported** on the Dapr provider — Dapr needs topic subscriptions declared at startup and can't add them at runtime. Calling `Subscribe(string, ...)` on it throws `AbpException`. - Publishing directly via `DaprClient.PublishEventAsync` bypasses ABP features like the **outbox/inbox** pattern; prefer `IDistributedEventBus` to keep them. ### Distributed locking with Dapr `Volo.Abp.DistributedLocking.Dapr` makes `IAbpDistributedLock` use Dapr's lock building block. Configure the store: ```csharp Configure<AbpDistributedLockDaprOptions>(options => { options.StoreName = "mystore"; // required // Owner (optional), DefaultExpirationTimeout (optional, default 2 min) }); ``` Usage is the standard ABP lock API: ```csharp await using (var handle = await _distributedLock.TryAcquireAsync("MyLockName")) { if (handle != null) { // exclusive access to the shared resource } } ``` Two differences from ABP's default lock providers: - `timeout` on `TryAcquireAsync` is ignored — Dapr doesn't wait to acquire. - The lock auto-expires after `DefaultExpirationTimeout` even if not released; there's no per-call expiration parameter. > ABP's docs note Dapr's distributed-lock building block is at Alpha stage and its API may change — for production locking, ABP still recommends the DistributedLock-library providers over Dapr. ### Security (App API token) When traffic flows through Dapr, protect your receive endpoints with the App API token. In an event-handling action, validate it: ```csharp [HttpPost("/stock-changed")] [Topic("pubsub", "StockChanged")] public async Task<IActionResult> OnStockChangedAsync([FromBody] StockCountChangedEto model) { HttpContext.ValidateDaprAppApiToken(); // throws if the token is missing/wrong return Ok(); } ``` `ValidateDaprAppApiToken()` checks the `dapr-api-token` header (no-op if you haven't configured App API token). Outside controllers, inject `IDaprAppApiTokenValidator`. Enabling App API token validation is strongly recommended so arbitrary callers can't hit your subscription endpoints. ## Validation - Confirm the Dapr sidecar is running and the app-id used in `RemoteServices.BaseUrl` matches the target's Dapr application id; a proxy call then reaches the target via service invocation with no call-site change. - For pub/sub, confirm Dapr can fetch the subscription list from `dapr/subscribe` and that published events arrive at `api/abp/dapr/event` and dispatch to the right handler. - For locking, acquire `TryAcquireAsync("MyLockName")` against the configured `StoreName` and verify mutual exclusion. - Hit a receive endpoint without a valid `dapr-api-token` header and confirm `ValidateDaprAppApiToken()` rejects it (once App API token is configured). ## Common Pitfalls - `Volo.Abp.EventBus.Dapr` is **publish-only**; to also receive events install `Volo.Abp.AspNetCore.Mvc.Dapr.EventBus` (it references the event bus package). - Don't call `MapSubscribeHandler` yourself — ABP does it internally; add `app.UseCloudEvents()` only if you want CloudEvents. - **Dynamic (string-based) events are not supported** over Dapr — `Subscribe(string, ...)` throws `AbpException`, because Dapr needs subscriptions declared at startup. - Publishing directly via `DaprClient.PublishEventAsync` bypasses ABP's outbox/inbox — go through `IDistributedEventBus` to keep them. - Dapr's distributed lock ignores the `TryAcquireAsync` `timeout` (no wait) and auto-expires after `DefaultExpirationTimeout` with no per-call override; its building block is Alpha — prefer the DistributedLock-library providers for production. - Enable App API token validation so arbitrary callers can't hit your subscription endpoints; `ValidateDaprAppApiToken()` is a no-op until the token is configured. ## See also - ABP Dapr integration: `https://github.com/abpframework/abp/blob/rel-10.5/docs/en/framework/dapr/index.md` - Distributed Event Bus: `https://github.com/abpframework/abp/blob/rel-10.5/docs/en/framework/infrastructure/event-bus/distributed/index.md` - Distributed Locking: `https://github.com/abpframework/abp/blob/rel-10.5/docs/en/framework/infrastructure/distributed-locking.md`
GitHub에서 보기