# Creating a new topic

## With the `ITopicBuilder`

### Creating the builder

Topics are usable in a given context: whether your consumer (MQTT client) will use it to publish or subscribe will change the validation rules. As an example, when publishing, a client is not allowed to use a topic containing wildcards although this is not a problem when subscribing.

When creating your builder, you will have to indicate the consumer of the topic it will build so that the builder can help you enforce this constraint.&#x20;

To summarize, here is how to create your builder:

```csharp
ITopicBuilder builderPub = new TopicBuilder(TopicConsumer.Publisher);
ITopicBuilder builderSub = new TopicBuilder(TopicConsumer.Subscriber);
```

By default, a builder has a maximum capacity of 32 levels (i.e. topics added). You can override this value when creating your builder:

```csharp
const int capacity = 3;
ITopicBuilder builder = new TopicBuilder(capacity, TopicConsumer.Publisher);
```

### Using your builder

#### Adding a topic

Adding topics can be done in various ways. It's up to you if you want to add a single value or several ones using the provided methods:

```csharp
// Single topic
builder = builder.AddTopic("HelloWorld");

// Several topics
builder = builder.AddTopics("Hello", "World");
// or
builder = builder.AddTopics(new List<string> { "Hello", "World" });
```

{% hint style="info" %}
A builder is an [immutable object](https://www.leadingagile.com/2018/03/immutability-in-java/), which means that **each operation that should have mutate it will instead return a new updated instance of itself**. Thanks to this specificity, a builder is thread safe by default.
{% endhint %}

{% hint style="info" %}
You may want to reuse a builder without performing operations on it, to do so, call `Clone()` on the instance that you want to duplicate
{% endhint %}

#### Adding wildcards

You can also add wildcards using the built in methods or the exposed constants. You are also free to use raw values but it may be more error prone.

```csharp
// Single level wildcard '+'
builder.AddSingleLevelWildcard();
// or
builder.AddTopic(Mqtt.Wildcard.SingleLevel.ToString());
// or
builder.AddTopic("+");

// Multi level wildcard '#'
builder.AddMultiLevelWildcard();
// or
builder.AddTopic(Mqtt.Wildcard.MultiLevel.ToString());
// or
builder.AddTopic("#");
```

#### Building your topic

Once all topics have been added, you can build the resulting `Topic`. This is pretty straightforward and all you have to to is to call the `Build` method

```csharp
var topic = builder.Build();
```

{% hint style="info" %}
A dedicated section bellow will provide you a better insight of this object&#x20;
{% endhint %}

### Exposed properties

You may want some more insights from your builder. This can be achieved using the exposed properties of your `ITopicBuilder` instance

| Name                 | Type            | Meaning                                                                                                                                          |
| -------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Consumer`           | `TopicConsumer` | Indicate the `TopicConsumer` of this instance                                                                                                    |
| `IsAppendingAllowed` | `bool`          | Indicate if appending to this topic is allowed or not. Attempting to append a value to the builder when this is `false` will throw an exception. |
| `IsEmpty`            | `bool`          | Indicate if the builder contains any value                                                                                                       |
| `Levels`             | `int`           | Indicate the number of levels of the topic to be built                                                                                           |
| `MaxLevel`           | `int`           | Indicate the maximum number of topics that can be added in this builder                                                                          |

## With the `Topic` utilities

### Creating a `Topic` from a value

When building an `ITopicBuilder`,  the resulting object will be an instance of `Topic`. However, if you already dispose of the full topic in its raw form, you can use directly create its appropriate representation.

```csharp
const string rawTopic = "my/raw/topic";

// With the default constructor
var topic = new Topic(rawTopic);

// With the static constructor
var topic = Topic.FromString(rawTopic);

// With the explicit cast
var topic = (Topic) rawTopic;
```

{% hint style="info" %}
The topics build this way will also be checked. However, it will be assumed that they are built for a subscriber
{% endhint %}

### Exploiting a `Topic`

Since the Topic is just the object oriented way of representing a raw string, you can still access its raw value but also check for additional information such as its level.

A default representation of a Topic is its value, which means all those calls result in the same output

```csharp
// Using its property
Console.WriteLine(topic.Value);

// Converting to string
Console.WriteLine(topic);
Console.WriteLine((string) topic);
Console.WriteLine(topic.ToString());
```

### Exposed properties

| Name   | Type   | Meaning                                   |
| ------ | ------ | ----------------------------------------- |
| Levels | int    | Number of levels of the represented topic |
| Value  | string | String representation of the topic        |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://pbouillon.gitbook.io/mqtttopicbuilder/creating-a-new-topic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
