microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
3ddf9fa76ec1801a0e3ca312c6d9855879571ac1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

core/docs/ReduceBreakingChangesPlan.md

525lines · modecode

1# Plan: Reduce Breaking Changes between Libraries/Microsoft.Teams.Apps and core/src/Microsoft.Teams.Apps
2
3## Context
4
5The `core/src/Microsoft.Teams.Apps` project is the next version of `Libraries/Microsoft.Teams.Apps`. The current samples all target the old library. This plan identifies every public API breaking change and proposes concrete changes to the **new library** to minimize migration friction, prioritized by impact across samples.
6
7---
8
9## Breaking Changes Inventory
10
11### BC-1: Context convenience methods removed (ALL 13 samples affected)
12
13**Decision: IMPLEMENT** (defer `Send(AdaptiveCard)` — avoid Teams.Cards dependency for now)
14
15**Old API:**
16```csharp
17await context.Send("text", cancellationToken);
18await context.Send(card, cancellationToken);
19await context.Reply("text", cancellationToken);
20await context.Reply(card, cancellationToken);
21await context.Typing("processing", cancellationToken);
22```
23
24**New API:**
25```csharp
26await context.SendActivityAsync("text", cancellationToken); // only string overload
27// No Send(AdaptiveCard), no Reply(), no Typing()
28```
29
30**Samples affected:** Echo, Cards, Dialogs, Graph, Meetings, MessageExtensions, Reactions, TargetedMessages, Threading, Tab, Lights
31
32**Proposed fix:** Add convenience methods to `Context<TActivity>`:
33- `Send(string text, CancellationToken)` -> wraps `SendActivityAsync(text)`
34- `Send(TeamsActivity activity, CancellationToken)` -> wraps `SendActivityAsync(activity)`
35- ~~`Send(AdaptiveCard card, CancellationToken)`~~ **DEFERRED** — review later to avoid Teams.Cards dependency
36- `Reply(string text, CancellationToken)` -> builds threaded reply activity
37- `Reply(TeamsActivity activity, CancellationToken)` -> builds threaded reply
38- ~~`Reply(AdaptiveCard card, CancellationToken)`~~ **DEFERRED** — same reason
39- `Typing(string? text, CancellationToken)` -> wraps `SendTypingActivityAsync()`
40
41**File:** `core/src/Microsoft.Teams.Apps/Context.cs`
42
43---
44
45### BC-2: No `context.Log` logger (12 samples affected)
46
47**Decision: IMPLEMENT** — `context.Log` with `.Info()`, `.Error()`, `.Debug()` delegating to `ILogger`
48
49**Old API:**
50```csharp
51context.Log.Info("message");
52context.Log.Error("error");
53context.Log.Debug("debug");
54```
55
56**New API:** No logger on context at all.
57
58**Samples affected:** Echo, Cards, Dialogs, Graph, Meetings, MessageExtensions, Reactions, TargetedMessages, Tab, Lights, BotBuilder, Deprecated.Controllers
59
60**Proposed fix:** Add `Log` property to `Context<TActivity>` that exposes an object with `.Info()`, `.Error()`, `.Debug()` methods, delegating to `Microsoft.Extensions.Logging.ILogger` sourced from DI. This preserves the old API surface while using the standard logging infrastructure.
61
62**File:** `core/src/Microsoft.Teams.Apps/Context.cs`
63
64---
65
66### BC-3: No middleware / `OnActivity` + `Use()` + `context.Next()` (5 samples affected)
67
68**Decision: REVIEW LATER**
69
70**Old API:**
71```csharp
72teams.Use(async context => {
73 // before
74 await context.Next();
75 // after
76});
77teams.OnActivity(async (context, cancellationToken) => {
78 context.Log.Info(context.AppId);
79 await context.Next();
80});
81```
82
83**New API:** No middleware pipeline. Router dispatches directly to matching routes. No `Next()` on context.
84
85**Samples affected:** Echo, Graph, Meetings, TargetedMessages (OnActivity as catch-all)
86
87**Note:** Need to investigate whether affected samples use `context.Next()` in a way that requires access to the Teams `Context<TActivity>` inside the middleware. If so, ASP.NET middleware won't be a sufficient replacement.
88
89**File:** New extension method in `core/src/Microsoft.Teams.Apps/Handlers/`
90
91---
92
93### BC-4: No `context.Ref` (ConversationReference) (2 samples affected)
94
95**Decision: DOC-ONLY**
96
97**Old API:**
98```csharp
99var conversationId = context.Ref.Conversation.Id;
100```
101
102**New API:** No `Ref` property. Must use `context.Activity.Conversation.Id` directly.
103
104**Samples affected:** Threading, TargetedMessages
105
106**Migration:** `context.Ref.Conversation.Id` -> `context.Activity.Conversation.Id`
107
108---
109
110### BC-5: No `context.AppId` (1 sample affected)
111
112**Decision: IMPLEMENT**
113
114**Old API:**
115```csharp
116context.Log.Info(context.AppId);
117```
118
119**New API:** No `AppId` on context.
120
121**Samples affected:** Echo
122
123**Proposed fix:** Add `AppId` property to `Context<TActivity>` reading from `TeamsBotApplication.AppId`.
124
125**File:** `core/src/Microsoft.Teams.Apps/Context.cs`
126
127---
128
129### BC-6: App.Builder() pattern removed (2 samples affected)
130
131**Decision: IMPLEMENT** — Add `App.Builder()` as a wrapper around ASP.NET DI
132
133**Old API:**
134```csharp
135var appBuilder = App.Builder()
136 .AddLogger(new ConsoleLogger(...))
137 .AddOAuth("graph");
138builder.AddTeams(appBuilder);
139```
140
141**New API:**
142```csharp
143builder.Services.AddTeamsBotApplication(options => {
144 options.AddOAuthFlow("graph");
145});
146```
147
148**Samples affected:** Graph, Meetings
149
150**Proposed fix:** Add `App.Builder()` that wraps the standard ASP.NET DI options pattern, providing a clear migration path from the old builder API.
151
152---
153
154### BC-7: `AddTeams()` extension target changed (ALL samples affected)
155
156**Decision: IMPLEMENT** — parameterless overload only
157
158**Old API:**
159```csharp
160builder.AddTeams(); // on WebApplicationBuilder
161builder.AddTeams(appBuilder); // with App.Builder
162```
163
164**New API:**
165```csharp
166builder.Services.AddTeams(); // on IServiceCollection
167```
168
169**Samples affected:** All
170
171**Proposed fix:** Add parameterless extension method on `WebApplicationBuilder` that delegates to `builder.Services.AddTeams()`.
172
173**File:** `core/src/Microsoft.Teams.Apps/TeamsBotApplication.HostingExtensions.cs`
174
175---
176
177### BC-8: Proactive messaging from app-level (1 sample affected)
178
179**Decision: IMPLEMENT**
180
181**Old API:**
182```csharp
183await teams.Send(conversationId, "text", cancellationToken: ct);
184await teams.Reply(conversationId, messageId, "text", ct);
185```
186
187**New API:** No `Send()`/`Reply()` convenience methods on `TeamsBotApplication`.
188
189**Samples affected:** Threading
190
191**Proposed fix:** Add convenience methods on `TeamsBotApplication`:
192- `Send(string conversationId, string text, ...)`
193- `Reply(string conversationId, string messageId, string text, ...)`
194
195**File:** `core/src/Microsoft.Teams.Apps/TeamsBotApplication.cs` or extension
196
197---
198
199### BC-9: `OnSignIn` / `OnSignInFailure` events removed (1 sample affected)
200
201**Decision: DOC-ONLY** — existing `context.OnSignIn` methods provide backward compat
202
203**Old API:**
204```csharp
205teams.OnSignIn(async (_, @event, cancellationToken) => { ... });
206teams.OnSignInFailure(async (context, cancellationToken) => { ... });
207```
208
209**New API:** Uses `OAuthFlow.OnSignInComplete()` and `OAuthFlow.OnSignInFailure()` callbacks.
210
211**Samples affected:** Graph
212
213**Migration:** The new pattern uses per-flow callbacks. Existing `context.OnSignIn` methods cover backward compat:
214```csharp
215var flow = teams.GetOAuthFlow("graph");
216flow.OnSignInComplete(handler);
217flow.OnSignInFailure(handler);
218```
219
220---
221
222### BC-10: Meeting handler renames (1 sample affected)
223
224**Decision: IMPLEMENT** — aliases without `[Obsolete]`
225
226**Old API:**
227```csharp
228teams.OnMeetingJoin(handler);
229teams.OnMeetingLeave(handler);
230```
231
232**New API:**
233```csharp
234teams.OnMeetingParticipantJoin(handler);
235teams.OnMeetingParticipantLeave(handler);
236```
237
238**Samples affected:** Meetings
239
240**Proposed fix:** Add `OnMeetingJoin()` and `OnMeetingLeave()` as aliases that call the new methods. No `[Obsolete]` attribute for now — will revisit later.
241
242**File:** `core/src/Microsoft.Teams.Apps/Handlers/MeetingExtensions.cs`
243
244---
245
246### BC-11: `OnSetting()` handler missing (1 sample affected)
247
248**Decision: REVIEW LATER**
249
250**Old API:**
251```csharp
252teams.OnSetting((context, cancellationToken) => { ... });
253```
254
255**New API:** No `OnSetting()` extension method.
256
257**Samples affected:** MessageExtensions
258
259**Note:** Need to clarify what activity type/invoke name `OnSetting()` matches before implementing.
260
261**File:** `core/src/Microsoft.Teams.Apps/Handlers/MessageExtension/MessageExtensionExtensions.cs`
262
263---
264
265### BC-12: Invoke handler return types changed (4 samples affected)
266
267**Decision: IMPLEMENT** — factory methods only (no implicit conversions)
268
269**Old API:** Handlers return library-specific response types:
270```csharp
271// AdaptiveCardAction returns ActionResponse
272return new ActionResponse.Message("text") { StatusCode = 400 };
273
274// TaskFetch/Submit returns Microsoft.Teams.Api.TaskModules.Response
275return new Microsoft.Teams.Api.TaskModules.Response(...);
276
277// MessageExtension returns Microsoft.Teams.Api.MessageExtensions.Response
278return response;
279```
280
281**New API:** Handlers return `InvokeResponse` or `InvokeResponse<T>`:
282```csharp
283Task<InvokeResponse> AdaptiveCardActionHandler(...)
284Task<InvokeResponse<TaskModuleResponse>> TaskModuleHandler(...)
285Task<InvokeResponse<MessageExtensionResponse>> MessageExtensionQueryHandler(...)
286```
287
288**Samples affected:** Cards, Dialogs, MessageExtensions, Lights
289
290**Proposed fix:** Add factory methods:
291- `InvokeResponse.Ok(body)` — wraps body with 200 status
292- `InvokeResponse.Error(status, body)` — wraps body with error status
293
294**File:** Invoke response types in core project
295
296---
297
298### BC-13: Activity type hierarchy changed (MEDIUM - affects type usage)
299
300**Decision: DOC-ONLY**
301
302**Old:** Activities come from `Microsoft.Teams.Api.Activities` (e.g., `MessageActivity`, `InvokeActivity`)
303**New:** Activities come from `Microsoft.Teams.Apps.Schema` (e.g., `MessageActivity : TeamsActivity`)
304
305**Migration:** Namespace imports change but member access stays the same. Provide namespace mapping table in migration docs.
306
307---
308
309### BC-14: `app.AddTab()` missing (1 sample affected)
310
311**Decision: REVIEW LATER**
312
313**Old API:**
314```csharp
315app.AddTab("dialog-form", "Web/dialog-form");
316```
317
318**New API:** No `AddTab()` method.
319
320**Samples affected:** Dialogs, Tab
321
322**Note:** Need to determine if `AddTab()` is just static file serving or also registers Teams tab config endpoints. This affects whether a simple "use `app.UseStaticFiles()`" migration note is sufficient.
323
324---
325
326## Sample Migration Difficulty Assessment
327
328| Sample | Difficulty | Key Blockers |
329|--------|-----------|-------------|
330| Samples.Echo | **Easy** | BC-1 (Send/Typing), BC-2 (Log), BC-3 (OnActivity/Next), BC-5 (AppId), BC-7 (AddTeams) |
331| Samples.Cards | **Easy** | BC-1 (Send), BC-2 (Log), BC-7, BC-12 (InvokeResponse) |
332| Samples.Reactions | **Easy** | BC-1 (Send), BC-2 (Log), BC-7 |
333| Samples.Threading | **Easy** | BC-1 (Send/Reply), BC-4 (Ref), BC-7, BC-8 (proactive) |
334| Samples.Dialogs | **Easy-Med** | BC-1 (Send), BC-2 (Log), BC-7, BC-12, BC-14 (AddTab) |
335| Samples.MessageExtensions | **Easy-Med** | BC-1, BC-2, BC-7, BC-11 (OnSetting), BC-12 |
336| Samples.TargetedMessages | **Easy-Med** | BC-1 (Send/Reply), BC-2, BC-3 (OnActivity), BC-7 |
337| Samples.Meetings | **Medium** | BC-1, BC-2, BC-3 (Use/Next), BC-6 (Builder), BC-7, BC-10 (renames) |
338| Samples.Graph | **Medium-Hard** | BC-1, BC-2, BC-3 (Use/Next), BC-6 (Builder), BC-7, BC-9 (SignIn events) |
339| Samples.BotBuilder | **Hard** | Entire `AddBotBuilder<>()` pattern missing |
340| Deprecated.Controllers | **N/A** | Already deprecated, no migration needed |
341
342---
343
344## Implementation Plan (ordered by impact)
345
346### Item 1: Add `Send()`, `Reply()`, `Typing()` convenience methods to Context
347- **File:** `core/src/Microsoft.Teams.Apps/Context.cs`
348- **Impact:** Resolves BC-1, unblocks ALL samples
349- **Details:** Add methods matching old signatures (except AdaptiveCard overloads — deferred). `Reply()` builds a threaded reply using `Activity.Conversation.Id` and `Activity.Id`.
350
351### Item 2: Add `context.Log` with `.Info()`, `.Error()`, `.Debug()` delegating to ILogger
352- **File:** `core/src/Microsoft.Teams.Apps/Context.cs`
353- **Impact:** Resolves BC-2, unblocks 12 samples
354- **Details:** Expose a `Log` property with `.Info()`, `.Error()`, `.Debug()` methods that delegate to `Microsoft.Extensions.Logging.ILogger` from DI. Preserves old API surface.
355
356### Item 3: Add `WebApplicationBuilder.AddTeams()` extension
357- **File:** `core/src/Microsoft.Teams.Apps/TeamsBotApplication.HostingExtensions.cs`
358- **Impact:** Resolves BC-7, unblocks ALL samples
359- **Details:** Parameterless `public static IServiceCollection AddTeams(this WebApplicationBuilder builder) => builder.Services.AddTeams();`
360
361### Item 4: Add `AppId` property to Context
362- **File:** `core/src/Microsoft.Teams.Apps/Context.cs`
363- **Impact:** Resolves BC-5
364- **Details:** `AppId` sourced from `TeamsBotApplication.AppId`.
365
366### Item 5: Add `App.Builder()` wrapper around ASP.NET DI
367- **Impact:** Resolves BC-6, unblocks Graph and Meetings samples
368- **Details:** `App.Builder()` returns a builder that wraps standard ASP.NET DI options pattern.
369
370### Item 6: Add `OnMeetingJoin`/`OnMeetingLeave` aliases
371- **File:** `core/src/Microsoft.Teams.Apps/Handlers/MeetingExtensions.cs`
372- **Impact:** Resolves BC-10
373- **Details:** Aliases to `OnMeetingParticipantJoin`/`OnMeetingParticipantLeave`. No `[Obsolete]` for now.
374
375### Item 7: Add proactive `Send()`/`Reply()` on TeamsBotApplication
376- **File:** `core/src/Microsoft.Teams.Apps/TeamsBotApplication.cs` or extension
377- **Impact:** Resolves BC-8, unblocks Threading sample
378
379### Item 8: Add `InvokeResponse.Ok()`/`InvokeResponse.Error()` factory methods
380- **Impact:** Resolves BC-12
381- **File:** Invoke response types in core project
382
383### Item 9: Document migration for architectural changes (no code)
384- `context.Ref` (BC-4): `context.Ref.Conversation.Id` -> `context.Activity.Conversation.Id`
385- SignIn events (BC-9): `teams.OnSignIn()` -> `flow.OnSignInComplete()` (existing context.OnSignIn covers compat)
386- Namespace changes (BC-13): Provide mapping table
387
388---
389
390## API Surface Gaps (from systematic comparison)
391
392These were identified by comparing the full public API surface between old and new libraries, beyond what the sample-driven analysis caught.
393
394### BC-15: MessageActivity fluent methods removed
395
396**Decision: IMPLEMENTED** — MessageActivity fluent extension methods added.
397
398Methods added: `WithText()`, `AddText()`, `WithSuggestedActions()`, `WithTextFormat()`, `WithAttachmentLayout()`, `AddAttachment()`, `AddStreamFinal()`.
399
400Not migrated (low priority, underlying properties commented out): `WithSpeak()`, `WithInputHint()`, `WithSummary()`, `WithImportance()`, `WithDeliveryMode()`, `WithExpiration()`, `Merge()`.
401
402---
403
404### BC-16: `AddSensitivityLabel()` missing on TeamsActivity
405
406**Decision: IMPLEMENTED** — Extension method added in `MessageActivityExtensions`.
407
408---
409
410### BC-17: Base Activity fluent `With*()` methods removed
411
412**Decision: IMPLEMENTED (mostly)** — Base activity fluent methods added.
413
414- **With* methods:** `WithId`, `WithChannelId`, `WithFrom`, `WithRecipient`, `WithRecipient(..., bool isTargeted)`, `WithConversation`, `WithServiceUrl`, `WithLocale`, `WithTimestamp`, `WithLocalTimestamp`, `WithData(ChannelData)`, `WithData(string, object?)`, `WithAppId`
415- **Add* methods:** `AddEntity`, `UpdateEntity`, `AddAIGenerated`, `AddFeedback(bool)`, `AddTargetedMessageInfo`, `AddCitation`, `AddMention`, `AddSensitivityLabel`, `AddClientInfo`
416- **Get* methods:** `GetAccountMention`
417
418Remaining gap: `WithRelatesTo` is still not migrated because core currently has no `ConversationReference` model.
419
420---
421
422### BC-18: Activity conversion methods removed (`ToMessage()`, `ToInvoke()`, etc.)
423
424**Decision: NOT MIGRATED** — The old library had `ToMessage()`, `ToInvoke()`, `ToEvent()`, etc. The new library uses `FromActivity()` static factory methods instead:
425
426```csharp
427// Old: activity.ToMessage()
428// New: MessageActivity.FromActivity(coreActivity)
429```
430
431---
432
433### BC-19: Missing activity types
434
435**Decision: REVIEW LATER**
436
437| Missing Type | Notes |
438|---|---|
439| `TypingActivity` | No class in new lib; typing handled via `TeamsActivityType.Typing` |
440| `EndOfConversationActivity` | Commented out / TODO |
441| `CommandActivity` / `CommandResultActivity` | Commented out / TODO |
442| `ConversationReference` | Entire class missing; no direct replacement |
443
444---
445
446### BC-20: Missing handler registration methods
447
448**Decision: REVIEW LATER** — 18 handler methods exist in the old library but not in the new.
449
450**Tab handlers (completely removed):**
451- `OnTabFetch`, `OnTabSubmit`, `OnConfigFetch`, `OnConfigSubmit`
452
453**Command handlers (removed):**
454- `OnCommand`, `OnCommandResult`
455
456**Infrastructure events (architectural change):**
457- `OnActivity`, `OnError`, `OnStart`, `OnActivityResponse`, `OnActivitySent`
458
459**Auth events (restructured to per-flow):**
460- `OnSignIn`, `OnSignInFailure`, `OnTokenExchange`, `OnVerifyState`
461
462**Other removed handlers:**
463- `OnTyping`, `OnHandoff`, `OnFeedback`, `OnExecuteAction`
464
465**Commented out in new library:**
466- `OnSetting`, `OnCardButtonClicked`, `OnTypeaheadSearch`, `OnAnswerSearch`, `OnReadReceipt`
467
468---
469
470### BC-21: Type incompatibilities
471
472**Decision: NOT MIGRATED** — Intentional architectural changes.
473
474| Property | Old Type | New Type |
475|---|---|---|
476| `Timestamp`, `LocalTimestamp` | `DateTime?` | `string?` |
477| `ServiceUrl` | `string?` | `Uri?` |
478| `ContentUrl`, `ThumbnailUrl` (Attachment) | `string?` | `Uri?` |
479| Enums (`TextFormat`, `InputHint`, etc.) | Enum types | String constants |
480| `Account` | Custom `Account` class | `ConversationAccount` |
481
482---
483
484### BC-22: `Conversation.ToThreadedConversationId()` missing
485
486**Decision: REVIEW LATER** — Static utility method for constructing threaded conversation IDs. Used by Threading sample. The new `TeamsBotApplication.Reply()` handles this internally, but direct usage in sample code would break.
487
488---
489
490### BC-23: MessageActivity commented-out properties
491
492**Decision: REVIEW LATER** — These properties exist in the old library but are commented out in the new:
493`Speak`, `InputHint`, `Summary`, `Importance`, `DeliveryMode`, `Expiration`, `Value`
494
495---
496
497### BC-24: SuggestedActions fluent methods removed
498
499**Decision: NOT MIGRATED** — Old `SuggestedActions` had `AddRecipients()`, `AddAction()`, `AddActions()` fluent methods. Use direct property assignment instead.
500
501---
502
503## Items to Review Later
504
505- **BC-1 (partial):** `Send(AdaptiveCard)` / `Reply(AdaptiveCard)` — blocked on Teams.Cards dependency decision
506- **BC-3:** Middleware / `OnActivity` / `Use()` / `Next()` — need to investigate sample usage patterns
507- **BC-11:** `OnSetting()` handler — need to clarify activity type/invoke name
508- **BC-14:** `AddTab()` — need to determine if it's static files only or also tab config endpoints
509- **BC-19:** Missing activity types (`TypingActivity`, `EndOfConversationActivity`, `CommandActivity`)
510- **BC-20:** Missing handler registration methods (Tab, Command, Infrastructure, commented-out)
511- **BC-22:** `Conversation.ToThreadedConversationId()` static utility
512- **BC-23:** MessageActivity commented-out properties
513
514---
515
516## Verification
517
518After each item:
5191. Build `core/src/Microsoft.Teams.Apps` to verify compilation
5202. Verify existing tests pass (if any)
5213. For each item, attempt to mentally trace migration of affected sample code to confirm the gap is closed
522
523After all items:
5241. Migrate Samples.Echo as proof-of-concept to validate the full compat surface
5252. Run the migrated sample to verify end-to-end functionality
526