Как создать менеджер строки подключения, чтобы определить, доступен ли сервер, и вернуть строку подключения кеша, если нет - PullRequest
2 голосов
/ 10 августа 2011

У меня время от времени подключается приложение, в котором есть сервер, на котором хранится информация о продуктах. Я использую кэш базы данных для локального хранения этой информации, поэтому, когда соединение недоступно, приложение все равно будет работать при попытке прочитать базу данных.

Поскольку база данных настроена, и у меня нет доступа для изменения таблиц, я не реализовал двухстороннее обновление, и он только загружает снимок. Побочный вопрос: возможно ли создать кеш базы данных и иметь двухстороннюю синхронизацию только с колонками отслеживания на клиентском компьютере? Я не могу добавить какие-либо столбцы или таблицы на сервер. Я знаю, что это может быть вопрос для отдельного поста, но если это так, то это полностью изменит мое направление для этой проблемы - на отдельный модуль, обнаруживающий и синхронизирующий базу данных и обрабатывающий любые ошибки синхронизации, которые выбрасываются и всегда подключаются к кэш.

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

Должен ли я добавить интерфейс к универсальному репозиторию, который обрабатывает возврат правильной строки и сообщает репозиторию, является ли он активным или нет? Мне нужно включить / отключить определенные функции в зависимости от состояния соединения, поэтому мне также понадобится свойство где-нибудь, чтобы при использовании этого хранилища можно было связать различные состояния элементов управления с этим состоянием.

Вместо этого я должен иметь оболочку, которая содержит, например, IRepository и IConnectionStringManager, а затем обрабатывает подачу и инициализацию строки подключения к репозиторию в зависимости от доступности? Эта оболочка предоставит хранилище и все необходимые свойства статуса.

Полагаю, я не уверен, что мне следует настроить мою программу на использование IRepository со всеми автоматическими средствами распознавания соединений или если у меня должен быть IRepositoryManager с IRepository и IConnectionStringManager.

Может быть, оба эти варианта неверны?

1 Ответ

1 голос
/ 10 августа 2011

Мне нравится, как Entity Framework позволяет вам предоставлять строку подключения в качестве аргумента конструктора для его контекстов. Таким образом, вы можете использовать инфраструктуру внедрения зависимостей для применения специальной логики при создании контекста, и вам нужно всего лишь изменить код в одном месте (при условии, что вы используете принципы DI). Вы можете сделать что-то подобное с вашей реализацией репозитория.

Обновление

Поскольку вы используете Entity Framework, вот идея того, как это может выглядеть в коде:

// DI Bindings, Ninject style
Bind<Func<MyContext>>().ToMethod(
    c => new MyContext(
             c.Kernel.Get<IConnectionManager>().IsOnline()
                 ? OnlineConnectionString 
                 : OfflineConnectionString));

// Usage
public class ThingRepository : IThingRepository 
{
    private Func<MyContext> _getContext;
    public ThingRepository(Func<MyContext> getContext)
    {
        _getContext = getContext;
    }

    public IEnumerable<Thing> GetAllThings()
    {
        using(var context = _getContext())
        {
            return context.Things.ToList();
        }
    }
}

Или, если вы предпочитаете использовать более явную реализацию фабрики:

public interface IMyContextFactory
{
    MyContextFactory Get();
}

public class MyContextFactory : IMyContextFactory
{
    private const string OnlineConnectionString = "...";
    private const string OfflineConnectionString = "...";
    private IConnectionManager _connectionManager;
    public MyContextFactory(IConnectionManager connectionManager)
    {
        _connectionManager = connectionManager;
    }
    public MyContextFactory Get() 
    {
        var connectionString = _connectionManager.IsOnline() 
            ? OnlineConnectionString 
            : OfflineConnectionString
        return new MyContext(connectionString);
    }
}

// DI Bindings, Ninject style
Bind<IMyContextFactory>().To<MyContextFactory>();

// Usage
public class ThingRepository : IThingRepository 
{
    private IMyContextFactory _myContextFactory;
    public ThingRepository(IMyContextFactory myContextFactory)
    {
        _myContextFactory = myContextFactory;
    }

    public IEnumerable<Thing> GetAllThings()
    {
        using(var context = _myContextFactory.Get())
        {
            return context.Things.ToList();
        }
    }
}
...