"""
Урок 14
--------

Реализация IoC контейнера

*Цель:* Реализовать IoC контейнер, устойчивый к изменению требований.

В результате выполнения домашнего задания Вы получите IoC, который можно будет
использовать в своих проектах.

В игре танки есть набор операций над игровыми объектами: движение по прямой,
поворот, выстрел. При этом содержание этих команд может отличаться для разных
игр, в зависимости от того, какие правила игры были выбраны пользователями.

Например, пользователи могут ограничить запас ход каждого танка некоторым
количеством топлива, а другой игре запретить поворачиваться танкам
по часовой стрелке и т.д.

IoC может помочь в этом случае, скрыв детали в стратегии разрешения зависимости.

Например, IoC.Resolve("двигаться прямо", obj); возвращает команду, которая чаще
всего является макрокомандой и осуществляет один шаг движения по прямой.

Реализовать IoC контейнер, который:
-----------------------------------

1. Разрешает зависимости с помощью метода, со следующей сигнатурой:
    T IoC.Resolve(string key, params object[] args);

1. Регистрация зависимостей также происходит с помощью метода Resolve
    IoC.Resolve("IoC.Register", "aaa", (args) => new A()).Execute();

    Зависимости можно регистрировать в разных "скоупах"
    IoC.Resolve("Scopes.New", "scopeId").Execute();
    IoC.Resolve("Scopes.Current", "scopeId").Exceute();

Указание: Для работы со скоупами используйте ThreadLocal контейнер.

Критерии оценки:
------------------

1. Интерфейс IoC устойчив к изменению требований.
    Оценка: 0 - 5 баллов (0 - совсем не устойчив,
    5 - преподаватель не смог построить ни одного контрпримера)

1. IoC предоставляет ровно один метод для всех операций. 3 балла

1. IoC предоставляет работу со скоупами для предотвращения сильной связности. 5 баллов.

1. Реализованы модульные тесты. 5 баллов

1. Реализованы многопоточные тесты. 2 балла
"""