Skip to content

Commit 589bdef

Browse files
miiitchCopilot
andcommitted
docs: fix NuGet README display and update documentation
- Add <PackageReadmeFile>README.md</PackageReadmeFile> to TypedItem.Lib.csproj so nuget.org picks up the README correctly - Rewrite root README.md: remove obsolete 'Before 2.0' content, modernize for v3.0 with quick start, type hierarchy and links to full docs - Fix api-reference.md: correct IncludeDeletedItems type (bool? → bool) and document its actual default behaviour - Fix api-reference.md: only ItemType carries [EditorBrowsable(Never)], not Deleted Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2243865 commit 589bdef

3 files changed

Lines changed: 77 additions & 129 deletions

File tree

README.md

Lines changed: 74 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,109 @@
11
# TypedItem
22

3-
This library is a set of method extensions other CosmosDb SQL Api to handle typed elements and soft delete in a container
3+
**TypedItem** is a .NET extension library for **Azure Cosmos DB (SQL API)** that adds typed item management, soft delete, and hierarchical type queries to any Cosmos DB container.
44

5-
## Why giving a type for giving a type in a CosmosDb Container.
5+
Each document stores a `_type` field computed from C# inheritance and `[ItemType]` attributes. This lets you safely store multiple item types in a single container and query them with full type safety.
66

7-
This is wellknown best practice for Cosmos DB (see: https://youtu.be/bQBeTeYUrR8?t=1074). This library helps you to hide the complexity of the type management
7+
## Installation
88

9-
## What are the constraints on my container?
10-
11-
TypedItem add specifics fields and methods in your documents:
12-
* ```_pk``` the partition key ( for 1.X version of the SDK)
13-
* ```_type``` the type of the item
14-
* ```_deleted``` the deletion status (SoftDelete)
15-
16-
Type and deletion status are handled by the extention methods
17-
18-
Starting with version 2.0, the library is compatible with the 3.X version of the SDK. The partition key is now managed by the fonction ```abstract PartitionKey GetPartitionKey()``` and the library doesn't need the ```_pk``` field anymore. This model let you manage the partition key as you want. Even for hierarchical partition key
19-
20-
### Before 2.0: How to add a type to a class ?
9+
```bash
10+
dotnet add package TypedItem
11+
```
2112

22-
You have to:
23-
* inherits from ```TypedItemBase```
24-
* add the attribute ```ItemType```
25-
* seal the class
13+
Requires **Microsoft.Azure.Cosmos 3.x** and **.NET 10**.
2614

27-
For example:
15+
## Quick start
2816

17+
### 1 — Define a partition-key base class
2918

3019
```csharp
31-
32-
[ItemType("person")]
33-
public sealed class PersonItem: TypedItemBase
34-
{
35-
36-
[JsonProperty("firstName")]
37-
public string FirstName { get; set; }
38-
39-
[JsonProperty("lastName")]
40-
public string LastName { get; set; }
41-
42-
[JsonProperty("birthdate")]
43-
public DateTime BirthDate { get; set; }
44-
}
20+
public class MyContainerItem : TypedItemBase
21+
{
22+
[JsonProperty("part")]
23+
public string Part { get; set; }
24+
25+
public override PartitionKey GetPartitionKey()
26+
=> CreatePartitionKey(Part);
27+
}
4528
```
46-
In the container, the type will be ```person```
4729

30+
### 2 — Define typed item classes
4831

49-
If you what to create type hierarchy you can do this:
32+
Annotate with `[ItemType("name")]`. Write operations require a `sealed` class.
5033

5134
```csharp
52-
53-
[ItemType("event")]
54-
public class EventItem: TypedItemBase
55-
{
35+
[ItemType("person")]
36+
public sealed class PersonItem : MyContainerItem
37+
{
38+
[JsonProperty("firstName")] public string FirstName { get; set; }
39+
[JsonProperty("lastName")] public string LastName { get; set; }
40+
}
41+
```
5642

57-
[JsonProperty("date")]
58-
public DateTime Date { get; set; }
59-
}
43+
### 3 — Use extension methods
6044

61-
[ItemType("phonecall")]
62-
public sealed class PhonecallItem: EventItem
63-
{
45+
All methods extend `Microsoft.Azure.Cosmos.Container` and `TransactionalBatch`:
6446

65-
[JsonProperty("date")]
66-
public int Duration { get; set; }
67-
}
47+
```csharp
48+
// Write
49+
await container.CreateTypedItemAsync(person);
50+
await container.UpsertTypedItemAsync(person);
51+
await container.ReplaceTypedItemAsync(person, person.Id);
6852

69-
[ItemType("teamsmeeting")]
70-
public sealed class TeamsMeeting: EventItem
71-
{
53+
// Read — throws CosmosException (404) if soft-deleted or wrong type
54+
var response = await container.ReadTypedItemAsync<PersonItem>(id, partitionKey);
7255

73-
[JsonProperty("peoples")]
74-
public string[] Peoples { get; set; }
75-
}
56+
// Soft-delete (sets _deleted = true via conditional PATCH)
57+
await container.SoftDeleteTypedItemAsync(person);
7658

59+
// Query
60+
var result = await container.QueryTypedItemAsync<PersonItem, PersonItem>(q => q);
7761
```
7862

79-
You can create 2 differents items in the container:
80-
* one with the type ```event.phonecall```
81-
* one with the type ```event.teamsmeeting```
82-
83-
You can query all the events at once too with the method ```QueryTypedItemAsync```
84-
85-
86-
### After 2.0: How to add a type to a class ?
63+
## Type hierarchy
8764

88-
You have to:
89-
* create a root class from ```TypedItemBase``` to manage the partition key
90-
* add the attribute ```ItemType```
91-
* seal the class
92-
93-
For example:
65+
Use C# inheritance with multiple `[ItemType]` attributes to build dot-separated type hierarchies:
9466

9567
```csharp
96-
97-
public class ContainerItem : TypedItemBase
98-
{
99-
[JsonProperty("part")]
100-
public string Part { get; set; }
101-
102-
public override PartitionKey GetPartitionKey()
103-
{
104-
return CreatePartitionKey(Part);
105-
}
106-
}
68+
[ItemType("event")] // non-sealed = queryable parent
69+
public class EventItem : MyContainerItem
70+
{
71+
[JsonProperty("date")] public DateTime Date { get; set; }
72+
}
73+
74+
[ItemType("phonecall")] // _type stored as "event.phonecall"
75+
public sealed class PhonecallItem : EventItem
76+
{
77+
[JsonProperty("duration")] public int Duration { get; set; }
78+
}
79+
80+
[ItemType("meeting")] // _type stored as "event.meeting"
81+
public sealed class MeetingItem : EventItem
82+
{
83+
[JsonProperty("attendees")] public string[] Attendees { get; set; }
84+
}
10785
```
10886

109-
```csharp
110-
111-
[ItemType("person")]
112-
public sealed class PersonItem: ContainerItem
113-
{
114-
115-
[JsonProperty("firstName")]
116-
public string FirstName { get; set; }
117-
118-
[JsonProperty("lastName")]
119-
public string LastName { get; set; }
120-
121-
[JsonProperty("birthdate")]
122-
public DateTime BirthDate { get; set; }
123-
}
124-
```
125-
In the container, the type will be ```person```
126-
127-
128-
If you what to create type hierarchy you can do this:
87+
`QueryTypedItemAsync` automatically filters by type:
12988

13089
```csharp
131-
132-
[ItemType("event")]
133-
public class EventItem: ContainerItem
134-
{
90+
// Returns only phone calls
91+
var calls = await container.QueryTypedItemAsync<PhonecallItem, PhonecallItem>(q => q);
13592

136-
[JsonProperty("date")]
137-
public DateTime Date { get; set; }
138-
}
139-
140-
[ItemType("phonecall")]
141-
public sealed class PhonecallItem: EventItem
142-
{
143-
144-
[JsonProperty("date")]
145-
public int Duration { get; set; }
146-
}
147-
148-
[ItemType("teamsmeeting")]
149-
public sealed class TeamsMeeting: EventItem
150-
{
93+
// Returns ALL events (phone calls + meetings)
94+
var events = await container.QueryTypedItemAsync<EventItem, EventItem>(q => q);
95+
```
15196

152-
[JsonProperty("peoples")]
153-
public string[] Peoples { get; set; }
154-
}
97+
## Fields stored in documents
15598

156-
```
99+
| JSON field | Description |
100+
|---|---|
101+
| `_type` | Dot-separated type identifier (e.g., `"event.phonecall"`) |
102+
| `_deleted` | Soft-delete flag (`true` = logically deleted) |
103+
| `id` | Document id (auto-generated if not set) |
157104

158-
You can create 2 differents items in the container:
159-
* one with the type ```event.phonecall```
160-
* one with the type ```event.teamsmeeting```
105+
## Links
161106

162-
You can query all the events at once too with the method ```QueryTypedItemAsync```
107+
- [Getting Started](docs/user/getting-started.md) — full usage guide with all options
108+
- [API Reference](docs/technical/api-reference.md) — all extension methods and types
109+
- [Running Tests](docs/technical/running-tests.md) — test infrastructure and known limitations

docs/technical/api-reference.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Executes a LINQ query filtered by `_type`. If `TFrom` is sealed, uses an exact m
129129
| Property | Type | Default | Description |
130130
|----------|------|---------|-------------|
131131
| `MaxItemCount` | `int` | SDK default | Max documents per page |
132-
| `IncludeDeletedItems` | `bool?` | `null` (include all) | Set `false` to exclude `_deleted = true` items |
132+
| `IncludeDeletedItems` | `bool` | `false` | When `false`, excludes soft-deleted items. When `true`, includes them. Note: if `queryOptions` is `null`, no filter is applied (all items returned) |
133133
| `ReadAllPages` | `bool` | `false` | Automatically fetch all pages |
134134
| `ContinuationToken` | `string?` | `null` | Resume from a previous page |
135135
| `MaxConcurrency` | `int?` | `null` | Max parallel partition queries |
@@ -189,4 +189,4 @@ Every item class ultimately inherits these JSON-mapped properties:
189189
| `ItemType` | `_type` | Type identifier set by the library |
190190
| `Deleted` | `_deleted` | Soft-delete flag (`false` by default) |
191191

192-
`ItemType` and `Deleted` are marked `[EditorBrowsable(EditorBrowsableState.Never)]` to reduce IDE noise — they are managed by the library, not by application code.
192+
`ItemType` is marked `[EditorBrowsable(EditorBrowsableState.Never)]` to reduce IDE noise — it is managed by the library, not by application code.

src/TypedItem/TypedItem.Lib/TypedItem.Lib.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<PackageProjectUrl>https://github.com/miiitch/TypedItem</PackageProjectUrl>
1212
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
1313
<PackageIcon>icon.png</PackageIcon>
14+
<PackageReadmeFile>README.md</PackageReadmeFile>
1415
</PropertyGroup>
1516

1617
<ItemGroup>

0 commit comments

Comments
 (0)