Skip to content

Redis TableDependency status notifier preview

Tomas Fabian edited this page Apr 7, 2020 · 8 revisions

EntityChangesViewModel with DomainEntitiesSubscriber tries to completely reconnect after Redis connection was lost and then reestablished. The above mentioned classes are in preview stage, if you have some spare time please try and test them as a proof of concept. Thank you.

Install-Package Joker.MVVM -Version 1.3.0 Install-Package Joker.Redis -Version 1.2.0-alpha1

Server side:

    private void SimulateServer(ISqlTableDependencyProvider<Product> productsChangesProvider)
    {
      this.productsChangesProvider =
        productsChangesProvider ?? throw new ArgumentNullException(nameof(productsChangesProvider));
      productsChangesProvider.SubscribeToEntityChanges();

      var schedulersFactory = new SchedulersFactory();
      var redisUrl = ConfigurationManager.AppSettings["RedisUrl"];

      var redisPublisher = new ProductSqlTableDependencyRedisProvider(productsChangesProvider,
        new RedisPublisher(redisUrl), schedulersFactory.TaskPool);
      redisPublisher.StartPublishing();
    }

Client side:

    private async Task InitializeClient()
    {
      var schedulersFactory = new WpfSchedulersFactory();
      var redisUrl = ConfigurationManager.AppSettings["RedisUrl"];

      var reactiveDataWithStatus = new ReactiveDataWithStatus<Product>();

      domainEntitiesSubscriber =
        new DomainEntitiesSubscriber<Product>(new RedisSubscriber(redisUrl), reactiveDataWithStatus, schedulersFactory);
      await domainEntitiesSubscriber.Subscribe();

      EntityChangesViewModel = new EntityChangesViewModel<ProductViewModel>(
        new ReactiveListViewModelFactory(reactiveDataWithStatus), reactiveDataWithStatus, schedulersFactory.Dispatcher);
    }

    public class ReactiveListViewModelFactory : IReactiveListViewModelFactory<ProductViewModel>
    {
      public ReactiveListViewModelFactory(ReactiveDataWithStatus<Product> reactiveDataWithStatus)
      {
        ReactiveDataWithStatus = reactiveDataWithStatus;
      }

      private ReactiveDataWithStatus<Product> ReactiveDataWithStatus { get; set; }
      
      public IReactiveListViewModel<ProductViewModel> Create()
      {      
        string connectionString = ConfigurationManager.ConnectionStrings["FargoEntities"].ConnectionString;
        var sampleDbContext = new SampleDbContext(connectionString);
        
        var schedulersFactory = new WpfSchedulersFactory();

        var reactiveProductsViewModel = new ReactiveProductsViewModel(sampleDbContext, ReactiveDataWithStatus, schedulersFactory);

        return reactiveProductsViewModel;
      }
    }
  <Grid DataContext="{Binding EntityChangesViewModel}">
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
      <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <StackPanel Margin="13" Orientation="Horizontal">
      <TextBlock Text="IsLoading: " />
      <TextBlock Text="{Binding ListViewModel.IsLoading}" />
      <TextBlock Margin="13,0,0,0" Text="IsOffline: " />
      <TextBlock Text="{Binding IsOffline}" />
    </StackPanel>

    <ListBox Grid.Row="1"
             Margin="13"
             ItemsSource="{Binding ListViewModel.Items}"
             SelectedItem="{Binding ListViewModel.SelectedItem}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Name}" />
        </DataTemplate>
      </ListBox.ItemTemplate>
    </ListBox>

  </Grid>