Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
We are building a WPF application using Microsoft.Extensions.DependencyInjection and we would like to change a little bit the structure that we have now.

Our WPF pages use viewmodels and communicate with the business logic layer using commands (ICommand) and, for instance, fetch data from Repositories that are registered as transients.

Since we have registered our IDbConnection as a scope, repositories depend on it and we are not in an ASP.NET Core app where the lifetime of a scope is equivalent to the lifetime of an HTTP request, the DB connection will never be closed because the scope never ends until the application is closed.

What I have tried:

Our idea is that whenever we run an ICommand, it needs to go through a middleware that will create a scope (CreateScope()) and will end after we have completed the task.
We do not see any issues of doing this yet. What do you think? Could there be any headaches?

Thanks.
Posted
Updated 3-Nov-23 4:43am
v2
Comments
[no name] 2-Nov-23 14:49pm    
What is a "task". What is the duration of "the" task? How does that relate to "stateless" and responsiveness? Does it involve commits, rollbacks and retries? Is there a callback mechanism? Is it required or optional?

(And single user becomes multi-user if a user can run multiple instances of an app. It happens.)
rw-MassimoTamburini 3-Nov-23 3:26am    
Hi thanks for the answer.
What is a "task". What is the duration of "the" task? Sorry I was not so accurate. For task I meant the execution of a code inside the Command.
How does that relate to "stateless" and responsiveness? What do you mean by "stateless" and resposiveness?
Does it involve commits, rollbacks and retries? Inside the Command we could have them.
Is there a callback mechanism? Is it required or optional? What specifically are you referring to?

I can give you an example of our current setup of a page:

MainPageConfigurationUserControl.xaml
<UserControl x:Class="SamplePlugin.Configuration.MainPageConfigurationUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mainPage="clr-namespace:SamplePlugin.Configuration.MainPage"
             mc:Ignorable="d"
             d:DesignHeight="600" d:DesignWidth="300" d:Background="White">
    <d:UserControl.DataContext>
        <mainPage:MainPageViewmodel/>
    </d:UserControl.DataContext>
    <Grid>
        <StackPanel >
            <Button x:Name="TestDialogButton" Command="{Binding TestDialogServerCommand}">Test dialog service</Button>
        </StackPanel>
        
    </Grid>
</UserControl>


MainPageViewModel.cs
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;

namespace SamplePlugin.Configuration.MainPage;

public partial class MainPageViewmodel : ObservableObject
{
    public ICommand TestDialogServerCommand { get; set; } = null!;
}


SamplePluginMainConfigurationPage.cs
using System.Data;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Media;
using Application;
using Application.Data;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Extensions.DependencyInjection;
using SamplePlugin.Configuration;
using SamplePlugin.Configuration.MainPage;
using Serilog;

namespace SamplePlugin;

public class SamplePluginMainConfigurationPage
{
    // other code...

    private MainPageConfigurationUserControl userControl = null!;
    private readonly MainPageViewmodel viewmodel = new();
    private readonly IServiceProvider provider;

    public SamplePluginMainConfigurationPage(IServiceProvider provider)
    {
        this.provider = provider;
        // This could also be AsyncRelayCommand
        viewmodel.TestDialogServerCommand = new RelayCommand(ExecuteTestDialogServerCommand);
    }

    private void ExecuteTestDialogServerCommand()
    {
        var dialogService = provider.GetService<IDialogService>()!;
        dialogService.ShowMessageBox("Hello from SamplePluginMainConfigurationPage");
    }

    public UserControl GetUserControl()
    {
        return userControl;
    }
   
    // other code...
}
[no name] 3-Nov-23 11:41am    
It "seemed" like you were asking about holding onto one database connection, and if there were any implications. I was simple talking in terms of a shared resource. It all depends on your app, and how it's used. When you talk about "closed connections" and make no reference to the "connection pool", it would seem you plan to do your own "pooling".

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900