Bruce Wayne 4 роки тому
батько
коміт
b9fa1181fb

+ 6 - 6
.editorconfig

@@ -1,4 +1,4 @@
-# 如果要从更高级别的目录继承 .editorconfig 设置,请删除以下行
+# 如果要从更高级别的目录继承 .editorconfig 设置,请删除以下行
 root = true
 
 [*]
@@ -19,6 +19,9 @@ indent_style = tab
 [*.csproj]
 indent_size = 2
 
+[*.props]
+indent_size = 2
+
 # c# 文件
 [*.cs]
 
@@ -106,7 +109,7 @@ csharp_style_conditional_delegate_call = true:warning
 
 # 修饰符首选项
 csharp_prefer_static_local_function = true:suggestion
-csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:silent
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
 
 # 代码块首选项
 csharp_prefer_braces = true:warning
@@ -121,7 +124,7 @@ csharp_style_prefer_index_operator = true:warning
 csharp_style_prefer_range_operator = true:suggestion
 csharp_style_throw_expression = true:suggestion
 csharp_style_unused_value_assignment_preference = discard_variable:silent
-csharp_style_unused_value_expression_statement_preference = discard_variable:silent
+csharp_style_unused_value_expression_statement_preference = discard_variable:none
 
 # "using" 指令首选项
 csharp_using_directive_placement = outside_namespace:warning
@@ -214,6 +217,3 @@ dotnet_naming_style.begins_with_i.required_prefix = I
 dotnet_naming_style.begins_with_i.required_suffix =
 dotnet_naming_style.begins_with_i.word_separator =
 dotnet_naming_style.begins_with_i.capitalization = pascal_case
-
-# IDE1006: 命名样式
-dotnet_diagnostic.IDE1006.severity = silent

+ 2 - 1
NatTypeTester.Models/Config.cs

@@ -1,9 +1,10 @@
 using ReactiveUI.Fody.Helpers;
 using STUN.Enums;
+using Volo.Abp.DependencyInjection;
 
 namespace NatTypeTester.Models
 {
-	public class Config
+	public class Config : ISingletonDependency
 	{
 		[Reactive]
 		public string StunServer { get; set; } = @"stun.syncthing.net";

+ 3 - 2
NatTypeTester.Models/NatTypeTester.Models.csproj

@@ -1,13 +1,14 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
+  <Import Project="..\common.props" />
+
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <LangVersion>latest</LangVersion>
-    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>
     <PackageReference Include="ReactiveUI.Fody" Version="14.1.1" />
+    <PackageReference Include="Volo.Abp.Core" Version="4.3.3" />
   </ItemGroup>
 
   <ItemGroup>

+ 10 - 0
NatTypeTester.Models/NatTypeTesterModelsModule.cs

@@ -0,0 +1,10 @@
+using JetBrains.Annotations;
+using Volo.Abp.Modularity;
+
+namespace NatTypeTester.Models
+{
+	[UsedImplicitly]
+	public class NatTypeTesterModelsModule : AbpModule
+	{
+	}
+}

+ 6 - 1
NatTypeTester.ViewModels/MainWindowViewModel.cs

@@ -8,10 +8,15 @@ using System.Collections.Generic;
 using System.IO;
 using System.Linq;
 using System.Reactive.Linq;
+using Volo.Abp.DependencyInjection;
 
 namespace NatTypeTester.ViewModels
 {
-	public class MainWindowViewModel : ReactiveObject, IScreen
+	[ExposeServices(
+		typeof(MainWindowViewModel),
+		typeof(IScreen)
+	)]
+	public class MainWindowViewModel : ViewModelBase, IScreen
 	{
 		public RoutingState Router { get; } = new();
 

+ 3 - 2
NatTypeTester.ViewModels/NatTypeTester.ViewModels.csproj

@@ -1,13 +1,14 @@
 <Project Sdk="Microsoft.NET.Sdk">
 
+  <Import Project="..\common.props" />
+
   <PropertyGroup>
     <TargetFramework>netstandard2.0</TargetFramework>
-    <LangVersion>latest</LangVersion>
-    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>
     <PackageReference Include="ReactiveUI.Fody" Version="14.1.1" />
+    <PackageReference Include="Volo.Abp.Core" Version="4.3.3" />
   </ItemGroup>
 
   <ItemGroup>

+ 10 - 0
NatTypeTester.ViewModels/NatTypeTesterViewModelModule.cs

@@ -0,0 +1,10 @@
+using JetBrains.Annotations;
+using Volo.Abp.Modularity;
+
+namespace NatTypeTester.ViewModels
+{
+	[UsedImplicitly]
+	public class NatTypeTesterViewModelModule : AbpModule
+	{
+	}
+}

+ 4 - 2
NatTypeTester.ViewModels/RFC3489ViewModel.cs

@@ -1,3 +1,4 @@
+using JetBrains.Annotations;
 using NatTypeTester.Models;
 using ReactiveUI;
 using ReactiveUI.Fody.Helpers;
@@ -13,9 +14,10 @@ using System.Threading.Tasks;
 
 namespace NatTypeTester.ViewModels
 {
-	public class RFC3489ViewModel : ReactiveObject, IRoutableViewModel
+	[UsedImplicitly]
+	public class RFC3489ViewModel : ViewModelBase, IRoutableViewModel
 	{
-		public string UrlPathSegment { get; } = @"RFC3489";
+		public string UrlPathSegment => @"RFC3489";
 		public IScreen HostScreen { get; }
 
 		private readonly Config _config;

+ 4 - 2
NatTypeTester.ViewModels/RFC5780ViewModel.cs

@@ -1,3 +1,4 @@
+using JetBrains.Annotations;
 using NatTypeTester.Models;
 using ReactiveUI;
 using ReactiveUI.Fody.Helpers;
@@ -13,9 +14,10 @@ using System.Threading.Tasks;
 
 namespace NatTypeTester.ViewModels
 {
-	public class RFC5780ViewModel : ReactiveObject, IRoutableViewModel
+	[UsedImplicitly]
+	public class RFC5780ViewModel : ViewModelBase, IRoutableViewModel
 	{
-		public string UrlPathSegment { get; } = @"RFC5780";
+		public string UrlPathSegment => @"RFC5780";
 		public IScreen HostScreen { get; }
 
 		private readonly Config _config;

+ 4 - 2
NatTypeTester.ViewModels/SettingViewModel.cs

@@ -1,11 +1,13 @@
+using JetBrains.Annotations;
 using NatTypeTester.Models;
 using ReactiveUI;
 
 namespace NatTypeTester.ViewModels
 {
-	public class SettingViewModel : ReactiveObject, IRoutableViewModel
+	[UsedImplicitly]
+	public class SettingViewModel : ViewModelBase, IRoutableViewModel
 	{
-		public string UrlPathSegment { get; } = @"Settings";
+		public string UrlPathSegment => @"Settings";
 		public IScreen HostScreen { get; }
 
 		public Config Config { get; }

+ 9 - 0
NatTypeTester.ViewModels/ViewModelBase.cs

@@ -0,0 +1,9 @@
+using ReactiveUI;
+using Volo.Abp.DependencyInjection;
+
+namespace NatTypeTester.ViewModels
+{
+	public abstract class ViewModelBase : ReactiveObject, ISingletonDependency
+	{
+	}
+}

+ 12 - 13
NatTypeTester/App.xaml

@@ -1,15 +1,14 @@
 <Application
-	x:Class="NatTypeTester.App"
-	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-	xmlns:ui="http://schemas.modernwpf.com/2019"
-	Startup="Application_Startup">
-	<Application.Resources>
-		<ResourceDictionary>
-			<ResourceDictionary.MergedDictionaries>
-				<ui:ThemeResources />
-				<ui:XamlControlsResources />
-			</ResourceDictionary.MergedDictionaries>
-		</ResourceDictionary>
-	</Application.Resources>
+    x:Class="NatTypeTester.App"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    xmlns:ui="http://schemas.modernwpf.com/2019">
+    <Application.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ui:ThemeResources />
+                <ui:XamlControlsResources />
+            </ResourceDictionary.MergedDictionaries>
+        </ResourceDictionary>
+    </Application.Resources>
 </Application>

+ 46 - 5
NatTypeTester/App.xaml.cs

@@ -1,16 +1,57 @@
-using NatTypeTester.Services;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using System;
 using System.Windows;
+using Volo.Abp;
 
 namespace NatTypeTester
 {
 	public partial class App
 	{
-		private void Application_Startup(object sender, StartupEventArgs e)
+		private readonly IHost _host;
+		private readonly IAbpApplicationWithExternalServiceProvider _application;
+
+		public App()
+		{
+			_host = CreateHostBuilder();
+			_application = _host.Services.GetRequiredService<IAbpApplicationWithExternalServiceProvider>();
+		}
+
+		protected override async void OnStartup(StartupEventArgs e)
+		{
+			try
+			{
+				await _host.StartAsync();
+				Initialize(_host.Services);
+				_host.Services.GetRequiredService<MainWindow>().Show();
+			}
+			catch (Exception ex)
+			{
+				MessageBox.Show(ex.Message, nameof(NatTypeTester), MessageBoxButton.OK, MessageBoxImage.Error);
+			}
+		}
+
+		protected override async void OnExit(ExitEventArgs e)
+		{
+			_application.Shutdown();
+			await _host.StopAsync();
+			_host.Dispose();
+		}
+
+		private void Initialize(IServiceProvider serviceProvider)
 		{
-			DI.Register();
+			_application.Initialize(serviceProvider);
+		}
 
-			MainWindow = DI.GetRequiredService<MainWindow>();
-			MainWindow.Show();
+		private static IHost CreateHostBuilder()
+		{
+			return Host.CreateDefaultBuilder()
+					.UseAutofac()
+					.ConfigureServices((hostContext, services) =>
+					{
+						services.AddApplication<NatTypeTesterModule>();
+					})
+					.Build();
 		}
 	}
 }

+ 2 - 1
NatTypeTester/MainWindow.xaml.cs

@@ -6,10 +6,11 @@ using System;
 using System.Linq;
 using System.Reactive.Disposables;
 using System.Reactive.Linq;
+using Volo.Abp.DependencyInjection;
 
 namespace NatTypeTester
 {
-	public partial class MainWindow
+	public partial class MainWindow : ISingletonDependency
 	{
 		public MainWindow(MainWindowViewModel viewModel,
 			RFC5780ViewModel rfc5780ViewModel,

+ 4 - 5
NatTypeTester/NatTypeTester.csproj

@@ -1,14 +1,12 @@
 <Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
 
+  <Import Project="..\common.props" />
+
   <PropertyGroup>
     <OutputType>WinExe</OutputType>
     <TargetFramework>net48</TargetFramework>
     <UseWPF>true</UseWPF>
     <ApplicationIcon>icon.ico</ApplicationIcon>
-    <LangVersion>latest</LangVersion>
-    <Nullable>enable</Nullable>
-    <Version>3.4</Version>
-    <Authors>HMBSbige</Authors>
   </PropertyGroup>
 
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
@@ -23,11 +21,12 @@
     <PackageReference Include="Costura.Fody" Version="5.3.0">
       <PrivateAssets>All</PrivateAssets>
     </PackageReference>
-    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
+    <PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
     <PackageReference Include="ModernWpfUI" Version="0.9.4" />
     <PackageReference Include="ReactiveUI.Events.WPF" Version="14.1.1" />
     <PackageReference Include="ReactiveUI.WPF" Version="14.1.1" />
     <PackageReference Include="Splat.Microsoft.Extensions.DependencyInjection" Version="11.1.1" />
+    <PackageReference Include="Volo.Abp.Autofac" Version="4.3.3" />
   </ItemGroup>
 
   <ItemGroup>

+ 27 - 0
NatTypeTester/NatTypeTesterModule.cs

@@ -0,0 +1,27 @@
+using JetBrains.Annotations;
+using NatTypeTester.Models;
+using NatTypeTester.ViewModels;
+using ReactiveUI;
+using Splat;
+using Splat.Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Autofac;
+using Volo.Abp.Modularity;
+
+namespace NatTypeTester
+{
+	[DependsOn(
+		typeof(AbpAutofacModule),
+		typeof(NatTypeTesterModelsModule),
+		typeof(NatTypeTesterViewModelModule)
+		)]
+	[UsedImplicitly]
+	public class NatTypeTesterModule : AbpModule
+	{
+		public override void PreConfigureServices(ServiceConfigurationContext context)
+		{
+			context.Services.UseMicrosoftDependencyResolver();
+			Locator.CurrentMutable.InitializeSplat();
+			Locator.CurrentMutable.InitializeReactiveUI(RegistrationNamespace.Wpf);
+		}
+	}
+}

+ 0 - 42
NatTypeTester/Services/DI.cs

@@ -1,42 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using ReactiveUI;
-using Splat;
-using Splat.Microsoft.Extensions.DependencyInjection;
-using System;
-
-namespace NatTypeTester.Services
-{
-	public static class DI
-	{
-		public static T GetRequiredService<T>()
-		{
-			var service = Locator.Current.GetService<T>();
-
-			if (service is null)
-			{
-				throw new InvalidOperationException($@"No service for type {typeof(T)} has been registered.");
-			}
-
-			return service;
-		}
-
-		public static void Register()
-		{
-			var services = new ServiceCollection();
-
-			services.UseMicrosoftDependencyResolver();
-			Locator.CurrentMutable.InitializeSplat();
-			Locator.CurrentMutable.InitializeReactiveUI(RegistrationNamespace.Wpf);
-
-			ConfigureServices(services);
-		}
-
-		private static IServiceCollection ConfigureServices(IServiceCollection services)
-		{
-			return services
-				.AddViewModels()
-				.AddViews()
-				.AddConfig();
-		}
-	}
-}

+ 0 - 41
NatTypeTester/Services/ServiceExtensions.cs

@@ -1,41 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.DependencyInjection.Extensions;
-using NatTypeTester.Models;
-using NatTypeTester.ViewModels;
-using NatTypeTester.Views;
-using ReactiveUI;
-
-namespace NatTypeTester.Services
-{
-	public static class ServiceExtensions
-	{
-		public static IServiceCollection AddViewModels(this IServiceCollection services)
-		{
-			services.TryAddSingleton<MainWindowViewModel>();
-			services.TryAddSingleton<RFC5780ViewModel>();
-			services.TryAddSingleton<RFC3489ViewModel>();
-			services.TryAddSingleton<SettingViewModel>();
-
-			services.TryAddSingleton<IScreen>(provider => provider.GetRequiredService<MainWindowViewModel>());
-
-			return services;
-		}
-
-		public static IServiceCollection AddViews(this IServiceCollection services)
-		{
-			services.TryAddSingleton<MainWindow>();
-			services.TryAddTransient<IViewFor<RFC5780ViewModel>, RFC5780View>();
-			services.TryAddTransient<IViewFor<RFC3489ViewModel>, RFC3489View>();
-			services.TryAddTransient<IViewFor<SettingViewModel>, SettingView>();
-
-			return services;
-		}
-
-		public static IServiceCollection AddConfig(this IServiceCollection services)
-		{
-			services.TryAddSingleton<Config>();
-
-			return services;
-		}
-	}
-}

+ 5 - 1
NatTypeTester/Views/RFC3489View.xaml.cs

@@ -1,3 +1,4 @@
+using JetBrains.Annotations;
 using NatTypeTester.Utils;
 using NatTypeTester.ViewModels;
 using ReactiveUI;
@@ -7,10 +8,13 @@ using System.Reactive.Disposables;
 using System.Reactive.Linq;
 using System.Windows.Controls;
 using System.Windows.Input;
+using Volo.Abp.DependencyInjection;
 
 namespace NatTypeTester.Views
 {
-	public partial class RFC3489View
+	[ExposeServices(typeof(IViewFor<RFC3489ViewModel>))]
+	[UsedImplicitly]
+	public partial class RFC3489View : ITransientDependency
 	{
 		public RFC3489View(RFC3489ViewModel viewModel)
 		{

+ 5 - 1
NatTypeTester/Views/RFC5780View.xaml.cs

@@ -1,3 +1,4 @@
+using JetBrains.Annotations;
 using NatTypeTester.Utils;
 using NatTypeTester.ViewModels;
 using ReactiveUI;
@@ -7,10 +8,13 @@ using System.Reactive.Disposables;
 using System.Reactive.Linq;
 using System.Windows.Controls;
 using System.Windows.Input;
+using Volo.Abp.DependencyInjection;
 
 namespace NatTypeTester.Views
 {
-	public partial class RFC5780View
+	[ExposeServices(typeof(IViewFor<RFC5780ViewModel>))]
+	[UsedImplicitly]
+	public partial class RFC5780View : ITransientDependency
 	{
 		public RFC5780View(RFC5780ViewModel viewModel)
 		{

+ 5 - 1
NatTypeTester/Views/SettingView.xaml.cs

@@ -1,11 +1,15 @@
+using JetBrains.Annotations;
 using NatTypeTester.ViewModels;
 using ReactiveUI;
 using STUN.Enums;
 using System.Reactive.Disposables;
+using Volo.Abp.DependencyInjection;
 
 namespace NatTypeTester.Views
 {
-	public partial class SettingView
+	[ExposeServices(typeof(IViewFor<SettingViewModel>))]
+	[UsedImplicitly]
+	public partial class SettingView : ITransientDependency
 	{
 		public SettingView(SettingViewModel viewModel)
 		{

+ 8 - 0
common.props

@@ -0,0 +1,8 @@
+<Project>
+  <PropertyGroup>
+    <LangVersion>latest</LangVersion>
+    <Version>3.4</Version>
+    <Nullable>enable</Nullable>    
+    <Authors>HMBSbige</Authors>
+  </PropertyGroup>
+</Project>