Я только начал использовать Unity Application Block, чтобы отделить мои классы и облегчить юнит-тестирование. Однако я столкнулся с проблемой циклических зависимостей.
У меня есть класс типа фасада, который является чат-ботом. Это одноэлементный класс, который обрабатывает все виды вторичных классов и обеспечивает центральное место для запуска и настройки бота. У меня также есть класс AccessManager, который, в общем-то, управляет доступом к командам и ресурсам бота. Суть сводится к тому, что у меня настроены классы так:
public class Bot
{
public string Owner { get; private set; }
public string WorkingDirectory { get; private set; }
private IAccessManager AccessManager;
private Bot()
{
// do some setup
// LoadConfig sets the Owner & WorkingDirectory variables
LoadConfig();
// init the access mmanager
AccessManager = new MyAccessManager(this);
}
public static Bot Instance()
{
// singleton code
}
...
}
И класс AccessManager:
public class MyAccessManager : IAccessManager
{
private Bot botReference;
public MyAccesManager(Bot botReference)
{
this.botReference = botReference;
SetOwnerAccess(botReference.Owner);
}
private void LoadConfig()
{
string configPath = Path.Combine(
botReference.WorkingDirectory,
"access.config");
// do stuff to read from config file
}
...
}
Я хотел бы изменить этот дизайн для использования блока приложений Unity. Я хотел бы использовать Unity для генерации одиночного бота и загрузки интерфейса AccessManager в каком-то методе начальной загрузки, который выполняется раньше, чем что-либо еще.
public static void BootStrapSystem()
{
IUnityContainer container = new UnityContainer();
// create new bot instance
Bot newBot = Bot.Instance();
// register bot instance
container.RegisterInstance<Bot>(newBot);
// register access manager
container.RegisterType<IAccessManager,MyAccessManager>(newBot);
}
И когда я хочу получить ссылку на Access Manager внутри конструктора Bot, я могу просто сделать:
IAcessManager accessManager = container.Resolve<IAccessManager>();
И в других местах системы, чтобы получить ссылку на синглота Бота:
// do this
Bot botInstance = container.Resolve<Bot>();
// instead of this
Bot botInstance = Bot.Instance();
Проблема в том, что метод BootStrapSystem()
взорвется. Когда я создаю экземпляр бота, он попытается разрешить IAccessManager, но не сможет, потому что я еще не зарегистрировал типы (это следующая строка). Но я не могу перенести регистрацию перед созданием бота, потому что в рамках регистрации мне нужно передать бота в качестве параметра! Круговые зависимости !! Г !!!
Это указывает на то, что у меня есть недостаток в том, как я это структурировал. Но как мне это исправить? Помогите !!