> For the complete documentation index, see [llms.txt](https://postica.gitbook.io/binding-system-3/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://postica.gitbook.io/binding-system-3/reference/extending/value-providers.md).

# Value Providers

New ways for a parameter or a modifier field to obtain its value.

A method path needs arguments. A modifier needs its factor. A converter needs its fallback. Each of those values comes from an **`IValueProvider`**, and that indirection is why any of them can be a constant, a binding, or something you wrote.

## The interfaces

```csharp
// Untyped: what the system uses when the type is not known at compile time.
public interface IValueProvider
{
    object UnsafeValue { get; }
}

// Typed: the fast path.
public interface IValueProvider<out T> : IValueProvider
{
    T Value { get; }
}
```

That is the whole contract. Every bind type implements it, which is why a bind field can be a parameter of another bind field.

## Where they are used

<table><thead><tr><th width="290">Slot</th><th>What it is</th></tr></thead><tbody><tr><td>Method and indexer parameters</td><td>Each one is a <code>BindDataParameter</code>, which is a value provider. See <a href="/binding-system-3/overview/paths.md#parameters">Paths and Parameters</a>.</td></tr><tr><td>Modifier fields</td><td>Any <code>Bind&#x3C;T></code> or <code>ReadOnlyBind&#x3C;T></code> field on a modifier.</td></tr><tr><td>Converter fields</td><td>The same.</td></tr><tr><td>Default values</td><td><code>DefaultValueProvider</code> supplies the default for a type when a binding has nothing to read.</td></tr></tbody></table>

## Writing one

```csharp
using Postica.BindingSystem;
using UnityEngine;

// A provider whose value is the current time. Handy for animation-driven parameters.
public class TimeValueProvider : IValueProvider<float>
{
    public float Value => Time.time;
    public object UnsafeValue => Value;
}
```

Use it wherever the system accepts a provider, for example when constructing bind data in code:

```csharp
var parameters = new IValueProvider[] { new TimeValueProvider() };
var data = new BindData(source, "Evaluate(Single)", parameters, mainParamIndex: 0);
```

{% hint style="info" %}
A provider is read every time the value is needed, so keep `Value` cheap. If it is expensive, cache it and invalidate on your own schedule.
{% endhint %}

## Provider factories

When the type is only known at runtime, implement `IValueProviderFactory` and produce the right closed provider on demand:

```csharp
public interface IValueProviderFactory
{
    bool TryCreateProvider(Type type, out IValueProvider provider);

    // A typed convenience with a default implementation.
    bool TryCreateProvider<T>(out IValueProvider<T> provider);
}
```

`SimpleBindData` itself implements this: asked for a provider of type `T`, it wraps itself in a `ReadOnlyBindLite<T>`. That single line is what lets any bind data act as a parameter to any other binding.

## Default values

`DefaultValueProvider` answers "what should this be when there is nothing to read?" It backs the **Nothing** entry in the bind path menu, where reads return the default and writes are discarded.

`[AllowDefaultValues]` on a bind field lets the field offer the default value of its type as an explicit choice:

```csharp
[AllowDefaultValues]
public Bind<Transform> optionalTarget;
```

## When to reach for this

Rarely, and that is the point: parameters being bindable already covers nearly everything. The cases that are genuinely left:

<table><thead><tr><th width="330">Case</th><th>Example</th></tr></thead><tbody><tr><td>A value from outside Unity's object graph</td><td>A remote config value, a save file entry, a platform capability.</td></tr><tr><td>A value with no serializable representation</td><td>Something computed from several systems at once.</td></tr><tr><td>Test doubles</td><td>A provider is the smallest way to feed a known value into a binding under test.</td></tr></tbody></table>

## Related pages

* [Paths and Parameters](/binding-system-3/overview/paths.md): where parameters come from.
* [Custom Modifiers](/binding-system-3/reference/extending/modifiers.md): making your modifier's fields bindable, which is the easier answer most of the time.
* [Bind Variables](/binding-system-3/overview/bind-variables.md): the authored alternative, for values a designer should control.
