Как избежать анти-паттерна ServiceLocator?

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

Итак, для того, чтобы обеспечить уровень доступа к данным правильными учетными данными текущего пользователя, мне предложили, чтобы мой ConfigurationProvider будет зависеть от случая ICurrentUserInSingletonScope() согласно 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);
}
Другие вопросы по тегам