1024programmer Asp.Net Deep understanding of dependency injection and inversion of control in WPF

Deep understanding of dependency injection and inversion of control in WPF

In-depth understanding of dependency injection and control inversion in WPF

In WPF development, dependency injection (Dependency Injection) and inversion of control (Inversion of Control) are the keys to program decoupling. They play a decisive role in today’s software engineering, and the two are inextricably linked. Today I will use a simple example to briefly describe how to implement dependency injection and control inversion in WPF. It is only for learning and sharing. If there are any deficiencies, please correct me.

In WPF development, Dependency Injection (Dependency Injection) and Inversion of Control (Inversion of Control) are program decoupled The key occupies a pivotal position in today’s software engineering, and there is an inseparable connection between the two. Today I will use a simple example to briefly describe how to implement dependency injection and control inversion in WPF. It is only for learning and sharing. If there are any deficiencies, please correct me.

What are dependency injection and inversion of control?

Dependency injection is also known as Inject dependencies, so what are dependencies? For example, in a class A, a certain function is implemented, and this function is implemented by another class B, then it means that A depends on B, and B is a dependency of A. Or object B that another object A depends on. An example is as follows:

namespace DemoIoc
 {
     public class MessageWriter
     {
         public void Print(string message)
         {
             Console.WriteLine($"MessageWriter.Write(message: \"{message}\")");
         }
     }

     public class Worker: BackgroundService
     {
         private readonly MessageWriter writer = new();

         protected override async Task ExecuteAsync(CancellationToken stoppingToken)
         {
             while (!stoppingToken.IsCancellationRequested)
             {
                 writer.Print($"Worker running at: {DateTimeOffset.Now}");
                 await Task.Delay(1_000, stoppingToken);
             }
         }
     }
 }

Note: In the above example, the Worker class depends on the MessageWriter class, so MessageWriter is a dependency of Worker. Hardcoded dependencies (like the previous example) can cause problems and should be avoided.

Strong dependencies have the following problems:

  • If you want to replace MessageWriter with a different implementation, you must modify the Worker class.
  • If the MessageWriter has dependencies, it must be configured by the Worker class and is difficult to initialize.
  • This implementation is difficult to unit test.

So how to solve the disadvantages caused by the above dependencies? The answer is dependency injection. This can be achieved through the following steps:

  • Use interfaces or base classes to abstract dependencies.
  • Register dependencies in the service container.
  • Inject the service into the constructor of the class that uses it.

.NET provides a built-in service container IServiceProvider. Services are usually registered when the application starts and appended to the IServiceCollection. After adding all services, you can use BuildServiceProvider to create a service container. The framework is responsible for creating instances of dependencies and releasing them when they are no longer needed.

In a simple sentence: Dependency injection (DI) parameterizes and interfaces the dependent objects, and converts the dependent objects into The creation and release are separated, so as to achieve decoupling and achieve Inversion of Control (IoC).

Inversion of Control (IoC) has the following two characteristics:

  • High-level codeCannot rely onlow-level code;
  • Abstract interfaceCannot rely on specific implementation;

Inversion of control solves the strong coupling of the code and increases the scalability of the code. Dependency injection turns the creation and release of dependency specific implementation classes and control implementation classes into Depends on interfaces or abstract classes and no longer controls the creation and release of interfaces. The two complement each other and achieve each other’s success.

Steps to implement dependency injection in WPF

1. Install DI library

First create a WPF application, and then install the dependency injection library [Microsoft.Extensions.DependencyInjection] provided by Microsoft in the Nuget package manager, as follows:

2. Create interfaces and implementation classes

Create the interface ITextService and implementation class TextService for testing, as shown below:

using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;

 namespaceDemoIoc
 {
     public interface ITextService
     {
        public string GetText();
     }

     public class TextService :ITextService
     {
         public string GetText()
         {
             return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
         }
     }
 }

3. Interface injection

Inject the ITextService interface where it needs to be called (such as MainWindow), as shown below:

namespace DemoIoc
 {
     /// 
     /// Interaction logic for MainWindow.xaml
     /// 
     public partial class MainWindow : Window
     {
         private ITextService textService;

         public MainWindow(ITextService textService)
         {
             this.textService = textService;
             InitializeComponent();
         }

         private void Window_Loaded(object sender, RoutedEventArgs e)
         {
             this.txtCurrentTime.Text = textService.GetText();
         }
     }
 }

Note: It can be seen from the above that MainWindow relies on the ITextService interface and does not rely on the implementation of the interface. This achieves dependency injection.

4. Configure container

In the startup program App.xaml.cs, add the current object members and the service provider object, and do it all at once when instantiating the service objectRegister so you can get it when you need it later. As shown below:

namespace DemoIoc
 {
     /// 
     /// Interaction logic for App.xaml
     /// 
     public partial class App : Application
     {
         /// 
         /// Get the current App instance
         /// 
         public new static App Current => (App)Application.Current;
         /// 
         /// Get the container that stores the application service
         /// 
         public IServiceProvider ServiceProvider { get; }

         publicApp()
         {
             ServiceProvider = ConfigureServices();
         }

         /// 
         /// Configure application services
         /// 
         private static IServiceProvider ConfigureServices()
         {
             var serviceCollection = new ServiceCollection()
                 .AddSingleton()
                 .AddSingleton();
                
             return serviceCollection.BuildServiceProvider();
         }

         protected override void OnStartup(StartupEventArgs e)
         {
             var mainWindow = ServiceProvider.GetRequiredService();
             mainWindow.Show();
         }
     }
 }

Note: In this example, MainWindow is instantiated through service registration, so you need to delete the StartUri property setting in the default App.xaml, otherwise you will be prompted that the default constructor does not exist.

Sample test

After the above steps, dependency injection and control inversion in WPF have been implemented. The test results are as follows:

Note: Normal output means dependency injection is successful.

Reference documentation

1. .Net dependency injection: https://learn.microsoft.com/zh-cn/dotnet/core/extensions/dependency-injection

The above is the entire content of dependency injection and inversion of control. I hope you can inspire others, learn together, and make progress together.

Author: Xiaoliu Gongzi

Source: http://www.cnblogs.com/hsiang/

The copyright of this article belongs to the author and the blog park. It is not easy to write an article. Originality is supported. Reprinting is welcome [like it]. Please keep this statement when reprinting, and provide a link to the original text in an obvious position on the article page. Thank you.

Follow personal public accounts and regularly update technology and workplace articles

x dashed; border-left: #e0e0e0 1px dashed; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 30px; font-family: Microsoft Yahei; font-size: 12px” id=”PSignature”>

Author: Xiaoliu Gongzi

Source: http://www.cnblogs.com/hsiang/

The copyright of this article belongs to the author and the blog park. It is not easy to write an article. Originality is supported. Reprinting is welcome [like it]. Please keep this statement when reprinting, and provide a link to the original text in an obvious position on the article page. Thank you.

Follow personal public accounts and regularly update technology and workplace articles

This article is from the internet and does not represent1024programmerPosition, please indicate the source when reprinting:https://www.1024programmer.com/811395

author: admin

Previous article
Next article

Leave a Reply

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

Contact Us

Contact us

181-3619-1160

Online consultation: QQ交谈

E-mail: [email protected]

Working hours: Monday to Friday, 9:00-17:30, holidays off

Follow wechat
Scan wechat and follow us

Scan wechat and follow us

Follow Weibo
Back to top
首页
微信
电话
搜索