zoukankan      html  css  js  c++  java
  • 使用 Microsoft.Extensions.DependencyInjection 进行依赖注入

    没有

    的日子,才是好日子~~~~~~~~~~

     

    Using .NET Core 3.0 Dependency Injection and Service Provider with WPF

     
     

    UPDATE: this article is based on a preview release of .NET Core 3.0. Please refer to Update on using HostBuilder, Dependency Injection and Service Provider with .NET Core 3.0 WPF applications for the latest one.

    We all know that .NET Core provides built-in support for Dependency Injection. We typically use it in ASP.NET Core (starting form the ConfigureServices method in the Startup.cs file), but the feature isn’t limited to this framework. So, as .NET Core 3.0 supports also Windows Clients development, we can use it in our WPF and Windows Forms applications.

    Let’s see how to do that, for example, in WPF using Visual Studio 2019. Suppose we want to create a service and we also have some application settings; we want to pass both of them to each window of our application via Dependency Injection.

    First of all, we must add the required NuGet packages to the project. Right click on the Solution Explorer, select the Manage NuGet Packages command and add the following packages (be sure to select the Include prerelease check):

    • Microsoft.Extensions.DependencyInjection
    • Microsoft.Extensions.Options.ConfigurationExtensions
    • Microsoft.Extensions.Configuration.Json
    Adding Dependency Injection support to a .NET Core 3.0 WPF application

    Adding Dependency Injection support to a .NET Core 3.0 WPF application

    These packages are necessary to enable Dependency Injection support (the first one) and to store and retrieve application settings in the classic appsettings.json file (the other ones). They will automatically get all the required dependencies.

    Then, let’s add a file named appsettings.json to the root folder of the project. Set its Build Action property to Content and Copy to Output Directory to Copy if newer:

    1
    2
    3
    4
    5
    6
    7
    {
      "AppSettings": {
        "StringSetting": "Value",
        "IntegerSetting": 42,
        "BooleanSetting": true
      }
    }

    All the prerequisites are met, so we can start writing our code. Let’s open the App.xaml file and remove the StartupUri property of the Application class. Then, we need to override the OnStartup method in App.xaml.cs:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public partial class App : Application
    {
        public IServiceProvider ServiceProvider { get; private set; }
     
        public IConfiguration Configuration { get; private set; }
     
        protected override void OnStartup(StartupEventArgs e)
        {
            var builder = new ConfigurationBuilder()
             .SetBasePath(Directory.GetCurrentDirectory())
             .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
     
            Configuration = builder.Build();
     
            var serviceCollection = new ServiceCollection();
            ConfigureServices(serviceCollection);
     
            ServiceProvider = serviceCollection.BuildServiceProvider();
     
            var mainWindow = ServiceProvider.GetRequiredService<MainWindow>();
            mainWindow.Show();
        }
     
        private void ConfigureServices(IServiceCollection services)
        {
            // ...
     
            services.AddTransient(typeof(MainWindow));
        }
    }

    In this method we create the Service Provider and configure the IoC container in a similar way of ASP.NET Core. We only need a bit of initialization. First of all, at line 9-13 we create an IConfiguration object that allows to read settings from the appsettings.json file (line 11). Then, we create an instance of a ServiceCollection class that will hold our services. Finally we call the ConfigureServices method (as we have in ASP.NET Core).

    Within the latter (lines 24-29), we register all the services used by the application in the exact same way of ASP. NET Core. We’ll complete this method in a moment, but for now let’s notice that we register also the MainWindow class (line 28). This is important because, in this way, the window itself becomes part of the Dependency Injection chain. It means that, after calling this method, at line 20-21 we can get it from the ServiceProvider and then show it. But, more important, it means that we can pass to the MainWindow constructor all the dependencies it needs, as we do for ASP.NET Core Controllers.

    Even if the actual services aren’t yet registered, we can run the application and see that everything works as expected.

    Now it’s time to complicate the things a bit. First of all, let’s create an AppSettings.cs file to hold configuration settings. This file will map the settings that we write in appsettings.json:

    1
    2
    3
    4
    5
    6
    7
    8
    public class AppSettings
    {
        public string StringSetting { get; set; }
     
        public int IntegerSetting { get; set; }
     
        public bool BooleanSetting { get; set; }
    }

    Then, create also a sample service with its interface:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public interface ISampleService
    {
        string GetCurrentDate();
    }
     
    public class SampleService : ISampleService
    {
        public string GetCurrentDate() => DateTime.Now.ToLongDateString();
    }

    Now we must register these services in the IoC Container, as usual:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    private void ConfigureServices(IServiceCollection services)
    {
        services.Configure<AppSettings>
            (Configuration.GetSection(nameof(AppSettings)));
         
        services.AddScoped<ISampleService, SampleService>();
     
        // ...
    }

    As said before, the MainWindow itself is in the IoC Container. So, when we get it from the Service Provider, it will automatically be injected with all required services, if any. So, we just need to modify its constructor:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public partial class MainWindow : Window
    {
        private readonly ISampleService sampleService;
        private readonly AppSettings settings;
     
        public MainWindow(ISampleService sampleService,
                          IOptions<AppSettings> settings)
        {
            InitializeComponent();
     
            this.sampleService = sampleService;
            this.settings = settings.Value;
        }
     
        // ...
    }

    Running this code, we’ll obtain a result like the following:

    The .NET Core 3.0 WPF application with dependencies injected

    The .NET Core 3.0 WPF application with dependecies injected

     原文地址:https://marcominerva.wordpress.com/2019/03/06/using-net-core-3-0-dependency-injection-and-service-provider-with-wpf/

     参考:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.0

     

  • 相关阅读:
    2013-10-31 《问题儿童居然一天两更!?》
    2013-10-31 《October 31st, 2013》
    2013-10-31 《三天里什么都没干……总之把目前为止的代码发了吧……》
    日怎么没人告诉我这博客可以改博文界面的显示宽度的
    俗话说打脸哦不打铁要趁热所以记录下替换图片的方法
    GUI好看码难写不是难写是难看我是说码难看不是GUI
    虽然保持了连续代码生产量但是仔细想想也没什么必要
    重写了电话本代码全面更新居然连续三天每天一个程序
    专注写字典三十年问你怕未又被编码卡了简直难以置信
    我就写个字典居然卡了两天重申一遍文字编码日你大爷
  • 原文地址:https://www.cnblogs.com/micro-chen/p/11852426.html
Copyright © 2011-2022 走看看