microsoft/teams.net

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v2.0.8

Branches

Tags

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

Clone

HTTPS

Download ZIP

core/docs/Core-Compat-PackageDependencies.md

227lines · modecode

1# Package Dependencies Design Document
2
3This document describes the package dependency changes introduced in the `next/core-decouple-fe` PR within the `core/` SDK. The key change is decoupling `Bot.Compat` from `Bot.Apps` so that both depend directly on `Bot.Core` as independent siblings.
4
5---
6
7## Before: Linear Dependency Chain
8
9Prior to this PR, `Bot.Compat` depended on `Bot.Apps`, which in turn depended on `Bot.Core`. This created a **linear chain** where Compat transitively pulled in everything from Apps.
10
11```mermaid
12graph BT
13 Core["Microsoft.Teams.Core<br/><i>net8.0 · net10.0</i><br/>Foundation Layer"]
14 Apps["Microsoft.Teams.Apps<br/><i>net8.0 · net10.0</i><br/>Teams Features Layer"]
15 Compat["Microsoft.Teams.Apps.BotBuilder<br/><i>net8.0 · net10.0</i><br/>Compatibility Layer"]
16
17 Apps -->|"ProjectReference"| Core
18 Compat -->|"ProjectReference"| Apps
19
20 style Core fill:#e1f5ff,stroke:#0d6efd
21 style Apps fill:#fff4e1,stroke:#fd7e14
22 style Compat fill:#ffe1f5,stroke:#d63384
23```
24
25### Problems with this structure
26
27- **Unnecessary coupling**: `Bot.Compat` only needs `Bot.Core` (activity model, conversation client, hosting), but was forced to take a dependency on the entire `Bot.Apps` layer (Teams-specific handlers, routing, streaming, Teams API client).
28- **Larger transitive closure**: Any consumer of `Bot.Compat` also pulled in `Bot.Apps` as a transitive dependency, even if they never used Teams-specific features.
29- **Breaking change risk**: Changes to `Bot.Apps` could break `Bot.Compat` consumers even when the Compat layer only used Core types.
30- **InternalsVisibleTo gap**: `Bot.Core` only exposed internals to `Bot.Apps`, so `Bot.Compat` had to go through Apps to access Core internals.
31
32---
33
34## After: Sibling Architecture
35
36This PR changes `Bot.Compat` to reference `Bot.Core` directly instead of `Bot.Apps`. Both `Apps` and `Compat` are now **independent siblings** that share only the `Core` foundation.
37
38```mermaid
39graph BT
40 Core["Microsoft.Teams.Core<br/><i>net8.0 · net10.0</i><br/>Foundation Layer"]
41 Apps["Microsoft.Teams.Apps<br/><i>net8.0 · net10.0</i><br/>Teams Features Layer"]
42 Compat["Microsoft.Teams.Apps.BotBuilder<br/><i>net8.0 · net10.0</i><br/>Compatibility Layer"]
43
44 Apps -->|"ProjectReference"| Core
45 Compat -->|"ProjectReference"| Core
46
47 style Core fill:#e1f5ff,stroke:#0d6efd
48 style Apps fill:#fff4e1,stroke:#fd7e14
49 style Compat fill:#ffe1f5,stroke:#d63384
50```
51
52---
53
54## Side-by-Side Comparison
55
56```mermaid
57graph TB
58 subgraph "Before"
59 direction BT
60 B_Core["Bot.Core"]
61 B_Apps["Bot.Apps"]
62 B_Compat["Bot.Compat"]
63 B_Apps -->|"ProjectReference"| B_Core
64 B_Compat -->|"ProjectReference"| B_Apps
65 end
66
67 subgraph "After"
68 direction BT
69 A_Core["Bot.Core"]
70 A_Apps["Bot.Apps"]
71 A_Compat["Bot.Compat"]
72 A_Apps -->|"ProjectReference"| A_Core
73 A_Compat -->|"ProjectReference"| A_Core
74 end
75
76 style B_Core fill:#e1f5ff
77 style B_Apps fill:#fff4e1
78 style B_Compat fill:#ffe1f5
79 style A_Core fill:#e1f5ff
80 style A_Apps fill:#fff4e1
81 style A_Compat fill:#ffe1f5
82```
83
84| Metric | Before | After |
85|--------|--------|-------|
86| Dependency depth from Compat | 3 (Compat → Apps → Core) | 2 (Compat → Core) |
87| Compat's transitive project refs | 2 (Apps + Core) | 1 (Core) |
88| Packages coupled to Bot.Apps | Apps + Compat | Apps only |
89| Core InternalsVisibleTo | Apps, Core.UnitTests | Apps, **Compat**, Core.UnitTests |
90
91---
92
93## What Changed
94
95### 1. `Bot.Compat.csproj` — dependency target changed
96
97```diff
98 <ItemGroup>
99- <ProjectReference Include="..\Microsoft.Teams.Apps\Microsoft.Teams.Apps.csproj" />
100+ <ProjectReference Include="..\Microsoft.Teams.Core\Microsoft.Teams.Core.csproj" />
101 </ItemGroup>
102```
103
104### 2. `Bot.Core.csproj` — InternalsVisibleTo added for Compat
105
106```diff
107 <ItemGroup>
108 <InternalsVisibleTo Include="Microsoft.Teams.Core.UnitTests" />
109 <InternalsVisibleTo Include="Microsoft.Teams.Apps" />
110+ <InternalsVisibleTo Include="Microsoft.Teams.Apps.BotBuilder" />
111 </ItemGroup>
112```
113
114### 3. Compat source code — rewritten to use Core types directly
115
116Types in `Bot.Compat` (e.g., `ActivitySchemaMapper`, `TeamsApiClient`, `CompatHostingExtensions`) were updated to import from `Microsoft.Teams.Core` namespaces instead of going through `Microsoft.Teams.Apps`.
117
118---
119
120## InternalsVisibleTo Relationships
121
122Before, only `Bot.Apps` could access Core internals. Now both sibling packages can.
123
124```mermaid
125graph LR
126 Core["Bot.Core"]
127 Apps["Bot.Apps"]
128 Compat["Bot.Compat"]
129 CoreTests["Bot.Core.UnitTests"]
130 AppsTests["Bot.Apps.UnitTests"]
131
132 Core -.->|"InternalsVisibleTo"| Apps
133 Core -.->|"InternalsVisibleTo<br/>(new)"| Compat
134 Core -.->|"InternalsVisibleTo"| CoreTests
135
136 Apps -.->|"InternalsVisibleTo"| AppsTests
137
138 style Core fill:#e1f5ff
139 style Apps fill:#fff4e1
140 style Compat fill:#ffe1f5
141 style CoreTests fill:#f0f0f0
142 style AppsTests fill:#f0f0f0
143```
144
145---
146
147## NuGet Dependencies Per Layer
148
149The external NuGet dependency layout is unchanged — but the transitive impact is different:
150
151```mermaid
152graph TD
153 subgraph "Bot.Core"
154 C1["AspNetCore.Authentication.JwtBearer"]
155 C2["AspNetCore.Authentication.OpenIdConnect"]
156 C3["System.Security.Cryptography.Pkcs"]
157 C4["Microsoft.Identity.Web.UI"]
158 C5["Microsoft.Identity.Web.AgentIdentities"]
159 end
160
161 subgraph "Bot.Apps"
162 A1["(no external NuGet packages)"]
163 end
164
165 subgraph "Bot.Compat"
166 X1["Microsoft.Bot.Builder.Integration<br/>.AspNet.Core 4.22.3"]
167 end
168
169 style C1 fill:#e1f5ff
170 style C2 fill:#e1f5ff
171 style C3 fill:#e1f5ff
172 style C4 fill:#e1f5ff
173 style C5 fill:#e1f5ff
174 style A1 fill:#fff4e1
175 style X1 fill:#ffe1f5
176```
177
178**Before**: A `Bot.Compat` consumer transitively received all NuGet packages from Core **plus** the entire `Bot.Apps` assembly.
179
180**After**: A `Bot.Compat` consumer only receives Core's NuGet packages. `Bot.Apps` is no longer in the transitive closure.
181
182---
183
184## Sample Application Dependency Patterns
185
186Samples demonstrate three independent entry points:
187
188```mermaid
189graph BT
190 Core["Bot.Core"]
191 Apps["Bot.Apps"]
192 Compat["Bot.Compat"]
193
194 CoreBot["CoreBot<br/><i>net10.0</i>"]
195 TeamsBot["TeamsBot<br/><i>net10.0</i>"]
196 CompatBot["CompatBot<br/><i>net8.0</i>"]
197
198 CoreBot --> Core
199 TeamsBot --> Apps
200 CompatBot --> Compat
201
202 Apps --> Core
203 Compat --> Core
204
205 style Core fill:#e1f5ff,stroke:#0d6efd
206 style Apps fill:#fff4e1,stroke:#fd7e14
207 style Compat fill:#ffe1f5,stroke:#d63384
208 style CoreBot fill:#f0f0f0
209 style TeamsBot fill:#f0f0f0
210 style CompatBot fill:#f0f0f0
211```
212
213| Entry Point | When to Use |
214|-------------|-------------|
215| **Bot.Core** directly | Minimal bots needing only core activity handling, middleware, and conversation client |
216| **Bot.Apps** | Teams-specific bots with typed handlers, routing, streaming, Teams API client |
217| **Bot.Compat** | Migrating existing Bot Framework v4 bots — no longer pulls in Bot.Apps transitively |
218
219---
220
221## Design Rationale
222
2231. **Decoupled Compat from Apps**: `Bot.Compat` only needs Core primitives (activities, conversation client, hosting). Removing the Apps dependency eliminates unnecessary coupling.
2242. **Smaller transitive closure**: Consumers of `Bot.Compat` no longer pull in the entire Teams-specific layer (`Bot.Apps`) as a transitive dependency.
2253. **Independent evolution**: `Bot.Apps` and `Bot.Compat` can now be versioned and modified independently without risk of cross-impact.
2264. **Direct internal access**: Adding `InternalsVisibleTo` for Compat on Core removes the need to route through Apps to access shared infrastructure like `BotHttpClient` and serialization contexts.
2275. **Clearer architecture**: The sibling pattern makes the SDK's layering explicit — Core is the shared foundation, Apps adds Teams features, Compat bridges to Bot Framework v4.
228