# Creating

The Scope API uses a builder pattern allowing you to inject any number of strictly typed values.

{% hint style="info" %}
Use the [lints](https://pub.dev/packages?q=lints) package to improve your code quality or [lint\_hard](https://pub.dev/packages/lint_hard) package if you want to grow hair on your chest.
{% endhint %}

You can then 'use' the injected values from any method called from within the context of the Scope.

```dart
import 'package:scope/scope.dart';

import 'my_scope_keys.dart';

void main() 
{
    Scope('main')
    ..value<int>(ageKey, 18)
    ..value<String>(nameKey, 'brett')
    ..run(() {
        someMethod();
    });
}
    
void someMethod() {
    // get values stored in the scope
    var age = use(ageKey);
    var name = use(nameKey);
    print('name: $name, age: $age');
}

```

In the above example we inject two values:

* an int with a key 'ageKey' and a value 18.
* a String with a key 'nameKey' and a value of 'brett'.

The age and name values are retrieved using the `use` method and the ScopeKey they where injected with.

You will notice that we pass the string 'main' to the Scope. This is an optional argument `debugName`. We recommend that you always pass a `debugName` as it is included when an Scope related exception is thrown and makes it easier to identify the source of a problem.

### ScopeKey

To inject and use a value you must create a typed key for each value using a ScopeKey:

```dart
// my_scope_keys.dart
final ageKey = ScopeKey<int>('ageKey');
final nameKey = ScopeKey<String>('nameKey');
final monthKey = ScopeKey<String>();
```

As the ScopeKey is typed the values returned from the `use` call are also correctly typed.

ScopeKeys are declared globally and it's is standard practice to place you Keys in a separate dart library as they need to be available at both the injection site and the `use` site.

You will notice that with the first two examples we provide the optional string argument `debugName`.  We recommend that you always pass a `debugName` as it is included when an ScopeKey related exception is thrown and makes it easier to identify the source of a problem.

## Example

We start by defining ScopeKeys for each value we want to inject.

```dart
final greetingKey = ScopeKey<String>();
final emphasisKey = ScopeKey<String>()
final dbKey = ScopeKey<Db>();
```

When then create a client (the Greeter class) that will 'use' values injected into the Scope.

```dart
class Greeter {
  Greeter()
      : greeting = use(greetingKey),
        emphasis = use(emphasisKey);

  final String greeting;
  final int emphasis;

  void greet(String name) {
    print('$greeting, $name${"!" * emphasis}');
    use(dbKey).createUser(name);
  }
}
```

Values are made available by creating a`Scope and injecting each of key/value pair into the Scope`.&#x20;

Once we have injected values into the Scope we call the Scope's `run` method.

Any method called directly or indirectly from within the `run` method has access to each of the values injected into the Scope.

```dart
import 'package:scope/scope.dart';
void main() {
  Scope()
    ..value<String>(greetingKey, 'Hello')
    ..value<int>(emphasisKey, 3)
    ..run(() {
    // The greet method calls `use` to retrieve the registered values
    Greeter().greet('world'); // 'Hello, world!!!'
  });

  Greeter().greet('you'); // throws: `MissingDependencyException`, because 
                          // `use()` is called outside the `Scope.run` method.
                          // The previously registered values arn't available
                          // outside of the scope of the run method.
}
```

You can create a Scope anywhere in your code that it might be useful.&#x20;
