# Dependency Injection

Web Atoms provides simple dependency injection with constructor and property injection.

## Registration

To register dependency can decorate class with following attributes.
* RegisterSingleton or DISingleton
* RegisterScoped
* Register or DITransient

### RegisterSingleton
Decorator `@RegisterSingleton` provides simple registration for singleton dependency.

```typescript
@RegisterSingleton
export default class TaskService extends BaseService {
    ... 
}
```

#### Abstract Class
In the following example, we want to inject class based on the current selected language by user.

```typescript
export abstract class BaseStringResourceType {
    public abstract get username(): string;
}

const BaseStringResource = (await import("./{lang}/StringResource"))
        as typeof BaseStringResourceType;

@DISingleton
export default BaseStringResource;
```

>/en-us/StringResource class
```typescript
export default class StringResource extends BaseStringResource {
    public username = "Username";
} 
```

>/hi/StringResource class
```typescript
export default class StringResource extends BaseStringResource {
    public username = "यूज़र नेम";
} 
```

UMD loader can expand variable when dependencies are loaded and DI will correctly inject dependency.

## Constructor Injection

```typescript
export default class TaskListViewModel extends AtomViewModel {

    // constructor injection..
    constructor(
        @Inject app: App,
        @Inject private taskService: TaskService,
        @Inject private stringResource: StringResource)
    {
        super(app);
    }
}
```

We recommend not to use View Model instead follow MVU pattern and inject dependencies directly into control by using
`@InjectProperty` decorator.

## Property Injection
```typescript
export default class TaskList extends AtomControl {

    @InjectProperty
    public taskService: TaskService;

    @InjectProperty
    public stringResource: StringResource;

    public async init() {
        // you can use your dependencies here..

        this.renderer = <div>
        ...
        </div>;
    }

}
```
