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
- 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
- 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 namelyPerson
andPersonService
which will implementIPersonService
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();
}
}
- 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 theStartuoUri
field fromApp.xaml
and add startup and exit event handlers. after making those changes theApp.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>
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();
}
}
- 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;
}
}
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)