Как избежать анти-паттерна ServiceLocator?
Чтобы получить доступ к базовому источнику данных, мне нужно предоставить учетные данные текущего пользователя, которых у меня нет заранее.
Итак, для того, чтобы обеспечить уровень доступа к данным правильными учетными данными текущего пользователя, мне предложили, чтобы мой ConfigurationProvider
будет зависеть от случая ICurrentUser
InSingletonScope()
согласно this answer
,
Как я понимаю, я проверю подлинность пользователя и свяжу ICurrentUser
после этого, и связывание остальной части моего уровня доступа к данным.
Поскольку аутентификация происходит в моей основной форме MDI, единственный способ, которым я вижу, как это сделать, - внедрить ядро Ninject в конструктор моей формы MDI.
Меня беспокоит тот факт, что, как я понимаю, необходимо зависеть от самого ядра Ninject, о котором совершенно не может быть и речи, поскольку тогда, если я не ошибаюсь, это будет так же, как использование ServiceLocator
анти-модель.
Итак, в этом сценарии, как избежать ServiceLocator
анти-модель?
1 ответ
Будет,
Вам не нужно иметь доступ к IResolutionRoot
в вашей форме аутентификации. Настроив. Я придумал пример реализации, которая использует IAuthenticationService
впрыскивается в вашу форму. После ввода пользователя вы можете позвонить SignIn()
и это изменит текущий экземпляр учетных данных.
С этого момента каждый раз, когда класс IDatabaseUserCredentials
получит этот экземпляр вместо экземпляра по умолчанию.
Я также сделал ConfigurationProvider
получить IConnectionStringProvider
вместо string
, Проверьте полную суть для полноценного рабочего примера.
public class AuthenticationService : IAuthenticationService
{
public void SignIn(string dbInstance, string login, string password)
{
var user = new DatabaseUserCredentials(dbInstance, login, password);
// A single point to manipulate your singleton instance
DatabaseUserCredentials.Current = user;
}
}
И привязки:
public override void Load()
{
Bind<Configuration>().ToProvider<ConfigurationProvider>();
Bind<IAuthenticationService>().To<AuthenticationService>();
Bind<IConnectionStringProvider>().To<ConnectionStringProvider>();
//Use Current user if available. If not, use default credentials.
Bind<IDatabaseUserCredentials>().ToMethod(c => DatabaseUserCredentials.Current ?? DatabaseUserCredentials.Default);
}