DEV Community

loading...

Leveraging ASP.NET structure in WPF

bazen-teklehaymanot
・2 min read

When creating ASP.NET project you get a lot thing out of the box which is helpful to facilitate the development process and setting structure to your project to some extent there by removing unnecessary repetitive work. in this article I would like to discuss how some of these concepts can be implemented in WPF app.

  • First lets create project, which can be done by running the following command or from visual studio
dotnet new wpf
Enter fullscreen mode Exit fullscreen mode
  • After creating the project lets add some necessary packages by running the following commands. here again the packages can be added from visual studio package manager. it is just matter of preference.
dotnet add [PROJECT] package Microsoft.Extensions.Hosting
dotnet add [PROJECT] package Microsoft.Extensions.Hosting.Abstractions
Enter fullscreen mode Exit fullscreen mode
  • Now that we have the project with the necessary packages added the next step is create new class which will be used to setup the configuration. in my case I will call this class ServiceHost and I will add service & model class namely Person and PersonService which will implement IPersonService
public interface IPersonService
    {
        Person GetPerson();
    }
    public class PersonService : IPersonService
    {
        public Person GetPerson() => new Person { Name = "Walker", Age = 23 };
    }


    public sealed class ServiceHost
    {
        private static readonly Lazy<IHost> _lazy = new Lazy<IHost>(() => CreatHost());
        public static IHost Instance
        {
            get { return _lazy.Value; }
        }
        private static IHost CreatHost()
        {
            return new HostBuilder()
                    .ConfigureAppConfiguration((context, configBuilder) =>
                    {
                        configBuilder.SetBasePath(context.HostingEnvironment.ContentRootPath);
                        configBuilder.AddJsonFile("appsettings.json", false);
                    })
                    .ConfigureServices((context, services) =>
                    {
                        services.AddTransient<IPersonService, PersonService>();
                        services.AddSingleton<MainWindow>();
                    })
                    .Build();
        }
    }
Enter fullscreen mode Exit fullscreen mode
  • Great now we are almost done. we have to change how the MainWindow gets started and we can start using injected services. we must remove the StartuoUri field from App.xaml and add startup and exit event handlers. after making those changes the App.xaml will look like this
<Application x:Class="WpfNetSample.App"

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfNetSample"
             Startup="Application_Startup"
             Exit="Application_Exit"
             >
    <Application.Resources>

    </Application.Resources>
</Application>
Enter fullscreen mode Exit fullscreen mode

the implementation of the startup and exit event handlers will look like the following.

public partial class App : Application
    {
        private async void Application_Startup(object sender, StartupEventArgs e)
        {
            await ServiceHost.Instance.StartAsync();
            var mainWindow = ServiceHost.Instance.Services.GetService<MainWindow>();
            mainWindow.Show();
        }

        private async void Application_Exit(object sender, ExitEventArgs e)
        {
            using (ServiceHost.Instance)
                await ServiceHost.Instance.StopAsync();
        }
    }
Enter fullscreen mode Exit fullscreen mode
  • Last but least lets try to use the injected service in the main window.
 public partial class MainWindow : Window
    {
        public Person Person { get; set; }
        public MainWindow(IPersonService personService)
        {
            Person = personService.GetPerson();
            InitializeComponent();
            DataContext = Person;
        }
    }
Enter fullscreen mode Exit fullscreen mode

In my case the main window only displays Person information since that is enough to show how to use the dependency injection, and not to go off topic. however I want to stress using this structure makes it easier to configure Logging, EF Core, Hosted service and many more. if any one is interested in exploring further let me know in the comment section and I'll write about it.

complete sample code can be found on my Github repo

Thank you for reading.

Discussion (0)

Forem Open with the Forem app