Dependency Injection in Windows Form or WPF Application .NET Core

Dependency Injection in Windows Form or WPF

In this article, we will attempt to implement a simple approach of implementing Dependency Injection in Windows Form or WPF.

We already looked at similar approaches for the .NET Core console, WebAPI application. Please see the below article for more details,

Today in this article, we will cover below aspects,

DI is a simple concept where you inject and use the services that you need, making your application highly efficient and lightweight.

With that understanding, we shall attempt to use DI in regular Desktop or Windows applications.

As already discussed in our previous article, there are a lot of benefits of the DI approach like,

  • Separation of concern
  • Independently deployable unit
  • Easily Testable units
  • High performance
  • Easy maintenance

Getting started

Here I am using a Forms/Windows .NET Core application.

Add ConfigureServices() method

Please add below ConfigureServices() method. This method can be used for registering all the required services within Service collection.

Here below I would like to inject the IBusinessLayer and ILogger object through the Forms object.

dependency injection windows form desktop app net core

Let’s now add Form1 which is currently my master Form and has the UI logic. Please register Form1 to above as services.

 services.AddScoped<Form1>()

Adding DI Container

Please update the Main() method as below.

We shall be injecting ILogger and IBusinessLayer object is as below,

        [STAThread]
        static void Main()
        {
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            var services = new ServiceCollection();

            ConfigureServices(services);

            using (ServiceProvider serviceProvider = services.BuildServiceProvider())
            {
                var form1 = serviceProvider.GetRequiredService<Form1>();
                Application.Run(form1);
            }
        }

Here we are assuming Form1 is the master form that holds other forms together.

In the above code, we added Form, logging ILogger, and IBusinessLayer interface to services collection and built the ServiceProvider for the required services. With that, both the logger object and business object instance can be DI via Constructor injection as and when required in other layers.

Add IBusinessObject and ILogger using DI to Forms App

The complete sample code is as below,

    
public partial class Form1 : Form
    {
        private readonly ILogger _logger;

        private readonly IBusinessLayer _business;
        public Form1(ILogger<Form1> logger, IBusinessLayer business)
        {
            _logger = logger;
            _business = business;
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                _logger.LogInformation("Form1 {BusinessLayerEvent} at {dateTime}", "Started", DateTime.UtcNow);

                // Perform Business Logic here 
                _business.PerformBusiness();

                MessageBox.Show("Hello .NET Core 3.0 . This is First Forms app in .NET Core");

                _logger.LogInformation("Form1 {BusinessLayerEvent} at {dateTime}", "Ended", DateTime.UtcNow);

            }
            catch (Exception ex)
            {
                //Log technical exception 
                _logger.LogError(ex.Message);
                //Return exception repsponse here
                throw;

            }

        }
    }

Let’s execute the application, we shall see all layers executed with logging as below,

blank

Using Generic HostBuilder for DI

We can also use Generic HostBuilder to perform a Dependency injection in Win forms.

If interested I have detailed about Using Generic HostBuilder for DI approach below,

Also If interested, I have talked in detail about How to implement dependency injection (DI) in a .NET Core Console application for logging and other business requirements.

Using similar techniques one can easily do DI in WPF application as well.

Can we make the above code better?

Please let me know if you have any better suggestions for performing DI in the Desktop application.

Other references :

Summary

Today we learned an easy approach of adding the Dependency Injection (DI) in newly supported Windows forms applications in .NET Core 3.0 and above. We understood with few custom changes as mentioned above, we can very much leverage DI in Desktop or Forms applications and can create maintainable and performative Win Form or Desktop applications.

Hope you liked this article! Please let me know your thoughts or if you have any better suggestions.

Please sound off your comments below.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



19 thoughts on “Dependency Injection in Windows Form or WPF Application .NET Core

    1. Hi AP- Thanks for your query. I believe for a regular .NET framework you could try leverage constructor injection and follow abstraction of the code base (using Interface) wherever possible. With this, you will be able to structure the code at least(if not UI) for the business layer or backend layer if any like MVC or MVVM pattern.

  1. Thank you for the Great article!!!
    I have the same question as the other guys. Beyond the master form, we could have many other forms with many dependencies, so how can I call another form from the master form?
    Assuming there’s a form2 and a button on master form, when I click the button it invokes form2, but if form2 has same dependencies as the master form, we can not just new it because its constructor, right?
    So how can I do this? Looking forward to your answer.

    1. Hello Christopher- As per my understanding, Form objects are unmanaged resources and perfrming DI for these object might give some unexpected result… it would be good to limit your DI for injecting other composite types and services only..and other forms like Forms2,3 can be used normal way ex. new Form2 () etc.. Let me know your thoughts.

  2. very nice article, when you need open the form from another form, how do you do?

    var form= new Form1();
    form.show();

    1. Thanks George. Glad you liked the article. As per my understanding, Form objects are unmanaged resources, they can be used in a regular way like using IDiposable pattern or example you mentioned. The advantage of the above pattern still lets you inject other composite types and services via DI. Let me know your thoughts.

  3. Your example is very good, but I tried to make Form1 called Form2, how would this be done in this project using DI?

    1. Thanks, Pericles for the feedback. You can use the same techniques of constructor injection for DI complex objects. If you can elaborate your question further more specific I can definitely provide you the resolution. Please let me know.

Leave a Reply

Your email address will not be published. Required fields are marked *