13
demo/WPFDemo/WPFDemo.Api/CommandLines/Options.cs
Normal file
13
demo/WPFDemo/WPFDemo.Api/CommandLines/Options.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using dotnetCampus.Cli;
|
||||
|
||||
namespace WPFDemo.Api.CommandLines
|
||||
{
|
||||
/// <summary>
|
||||
/// 启动参数
|
||||
/// </summary>
|
||||
public class Options
|
||||
{
|
||||
[Option("Name")]
|
||||
public string? Name { set; get; }
|
||||
}
|
||||
}
|
||||
6
demo/WPFDemo/WPFDemo.Api/Properties/AssemblyInfo.cs
Normal file
6
demo/WPFDemo/WPFDemo.Api/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using dotnetCampus.Telescope;
|
||||
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
[assembly: MarkExport(typeof(StartupTask), typeof(StartupTaskAttribute))]
|
||||
22
demo/WPFDemo/WPFDemo.Api/Startup/Foo1Startup.cs
Normal file
22
demo/WPFDemo/WPFDemo.Api/Startup/Foo1Startup.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
namespace WPFDemo.Api.Startup
|
||||
{
|
||||
[StartupTask(BeforeTasks = StartupNodes.CoreUI, AfterTasks = StartupNodes.Foundation)]
|
||||
public class Foo1Startup : StartupTask
|
||||
{
|
||||
protected override Task RunAsync(StartupContext context)
|
||||
{
|
||||
context.Logger.LogInfo("Foo1 Startup");
|
||||
return base.RunAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
demo/WPFDemo/WPFDemo.Api/Startup/OptionStartup.cs
Normal file
16
demo/WPFDemo/WPFDemo.Api/Startup/OptionStartup.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
namespace WPFDemo.Api.Startup
|
||||
{
|
||||
[StartupTask(BeforeTasks = StartupNodes.Foundation, AfterTasks = "LibStartup")]
|
||||
class OptionStartup : StartupTask
|
||||
{
|
||||
protected override Task RunAsync(StartupContext context)
|
||||
{
|
||||
context.Logger.LogInfo("Command " + context.CommandLineOptions.Name);
|
||||
|
||||
return CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Reflection;
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using dotnetCampus.Telescope;
|
||||
|
||||
namespace WPFDemo.Api.StartupTaskFramework
|
||||
{
|
||||
public class AssemblyMetadataExporter
|
||||
{
|
||||
public AssemblyMetadataExporter(Assembly[] assemblies)
|
||||
{
|
||||
_assemblies = assemblies;
|
||||
}
|
||||
|
||||
public IEnumerable<StartupTaskMetadata> ExportStartupTasks()
|
||||
{
|
||||
var collection = Export<StartupTask, StartupTaskAttribute>();
|
||||
return collection.Select(x => new StartupTaskMetadata(x.RealType.Name.Replace("Startup", ""), x.CreateInstance)
|
||||
{
|
||||
Scheduler = x.Attribute.Scheduler,
|
||||
BeforeTasks = x.Attribute.BeforeTasks,
|
||||
AfterTasks = x.Attribute.AfterTasks,
|
||||
//Categories = x.Attribute.Categories,
|
||||
CriticalLevel = x.Attribute.CriticalLevel,
|
||||
});
|
||||
}
|
||||
|
||||
public IEnumerable<AttributedTypeMetadata<TBaseClassOrInterface, TAttribute>> Export<TBaseClassOrInterface, TAttribute>() where TAttribute : Attribute
|
||||
{
|
||||
return AttributedTypes.FromAssembly<TBaseClassOrInterface, TAttribute>(_assemblies);
|
||||
}
|
||||
|
||||
private readonly Assembly[] _assemblies;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using dotnetCampus.Cli;
|
||||
using dotnetCampus.Configurations;
|
||||
using dotnetCampus.Configurations.Core;
|
||||
using WPFDemo.Api.CommandLines;
|
||||
|
||||
namespace WPFDemo.Api.StartupTaskFramework
|
||||
{
|
||||
public class StartupContext : IStartupContext
|
||||
{
|
||||
public StartupContext(IStartupContext startupContext, CommandLine commandLine, StartupLogger logger, FileConfigurationRepo configuration, IAppConfigurator configs)
|
||||
{
|
||||
_startupContext = startupContext;
|
||||
Logger = logger;
|
||||
Configuration = configuration;
|
||||
Configs = configs;
|
||||
CommandLine = commandLine;
|
||||
CommandLineOptions = CommandLine.As<Options>();
|
||||
}
|
||||
|
||||
public StartupLogger Logger { get; }
|
||||
|
||||
public CommandLine CommandLine { get; }
|
||||
|
||||
public Options CommandLineOptions { get; }
|
||||
|
||||
public FileConfigurationRepo Configuration { get; }
|
||||
|
||||
public IAppConfigurator Configs { get; }
|
||||
|
||||
public Task<string> ReadCacheAsync(string key, string @default = "")
|
||||
{
|
||||
return Configuration.TryReadAsync(key, @default);
|
||||
}
|
||||
|
||||
private readonly IStartupContext _startupContext;
|
||||
public Task WaitStartupTaskAsync(string startupKey)
|
||||
{
|
||||
return _startupContext.WaitStartupTaskAsync(startupKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
|
||||
namespace WPFDemo.Api.StartupTaskFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 和项目关联的日志
|
||||
/// </summary>
|
||||
public class StartupLogger : StartupLoggerBase
|
||||
{
|
||||
public void LogInfo(string message)
|
||||
{
|
||||
Debug.WriteLine(message);
|
||||
}
|
||||
|
||||
public override void ReportResult(IReadOnlyList<IStartupTaskWrapper> wrappers)
|
||||
{
|
||||
var stringBuilder = new StringBuilder();
|
||||
foreach (var keyValuePair in MilestoneDictionary)
|
||||
{
|
||||
stringBuilder.AppendLine($"{keyValuePair.Key} - [{keyValuePair.Value.threadName}] Start:{keyValuePair.Value.start} Elapsed:{keyValuePair.Value.elapsed}");
|
||||
}
|
||||
|
||||
Debug.WriteLine(stringBuilder.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using dotnetCampus.Cli;
|
||||
using dotnetCampus.Configurations.Core;
|
||||
|
||||
namespace WPFDemo.Api.StartupTaskFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 和项目关联的启动管理器,用来注入业务相关的逻辑
|
||||
/// </summary>
|
||||
public class StartupManager : StartupManagerBase
|
||||
{
|
||||
public StartupManager(CommandLine commandLine, FileConfigurationRepo configuration, Func<Exception, Task> fastFailAction, IMainThreadDispatcher mainThreadDispatcher) : base(new StartupLogger(), fastFailAction, mainThreadDispatcher)
|
||||
{
|
||||
var appConfigurator = configuration.CreateAppConfigurator();
|
||||
Context = new StartupContext(StartupContext, commandLine, (StartupLogger) Logger, configuration, appConfigurator);
|
||||
}
|
||||
|
||||
private StartupContext Context { get; }
|
||||
|
||||
protected override Task<string> ExecuteStartupTaskAsync(StartupTaskBase startupTask, IStartupContext context, bool uiOnly)
|
||||
{
|
||||
return base.ExecuteStartupTaskAsync(startupTask, Context, uiOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
namespace WPFDemo.Api.StartupTaskFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 包含预设的启动节点。
|
||||
/// </summary>
|
||||
public class StartupNodes
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础服务(日志、异常处理、容器、生命周期管理等)请在此节点之前启动,其他业务请在此之后启动。
|
||||
/// </summary>
|
||||
public const string Foundation = "Foundation";
|
||||
|
||||
/// <summary>
|
||||
/// 需要在任何一个 Window 创建之前启动的任务请在此节点之前。
|
||||
/// 此节点之后将开始启动 UI。
|
||||
/// </summary>
|
||||
public const string CoreUI = "CoreUI";
|
||||
|
||||
/// <summary>
|
||||
/// 需要在主 <see cref="Window"/> 创建之后启动的任务请在此节点之后。
|
||||
/// 此节点完成则代表主要 UI 已经初始化完毕(但不一定已显示)。
|
||||
/// </summary>
|
||||
public const string UI = "UI";
|
||||
|
||||
/// <summary>
|
||||
/// 应用程序已完成启动。如果应该显示一个窗口,则此窗口已布局、渲染完毕,对用户完全可见,可开始交互。
|
||||
/// 不被其他业务依赖的模块可在此节点之后启动。
|
||||
/// </summary>
|
||||
public const string AppReady = "AppReady";
|
||||
|
||||
/// <summary>
|
||||
/// 任何不关心何时启动的启动任务应该设定为在此节点之前完成。
|
||||
/// </summary>
|
||||
public const string StartupCompleted = "StartupCompleted";
|
||||
}
|
||||
}
|
||||
24
demo/WPFDemo/WPFDemo.Api/StartupTaskFramework/StartupTask.cs
Normal file
24
demo/WPFDemo/WPFDemo.Api/StartupTaskFramework/StartupTask.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
|
||||
namespace WPFDemo.Api.StartupTaskFramework
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示一个和当前业务强相关的启动任务
|
||||
/// </summary>
|
||||
public class StartupTask : StartupTaskBase
|
||||
{
|
||||
protected sealed override Task RunAsync(IStartupContext context)
|
||||
{
|
||||
return RunAsync((StartupContext) context);
|
||||
}
|
||||
|
||||
protected virtual Task RunAsync(StartupContext context)
|
||||
{
|
||||
return CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
demo/WPFDemo/WPFDemo.Api/WPFDemo.Api.csproj
Normal file
20
demo/WPFDemo/WPFDemo.Api/WPFDemo.Api.csproj
Normal file
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\dotnetCampus.ApplicationStartupManager\dotnetCampus.ApplicationStartupManager.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="dotnetCampus.CommandLine" Version="3.3.1-alpha03"/>
|
||||
<PackageReference Include="dotnetCampus.Configurations" Version="1.6.9" />
|
||||
<PackageReference Include="dotnetCampus.TelescopeSource" Version="1.0.0-alpha02" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
8
demo/WPFDemo/WPFDemo.App/App.xaml
Normal file
8
demo/WPFDemo/WPFDemo.App/App.xaml
Normal file
@@ -0,0 +1,8 @@
|
||||
<Application x:Class="WPFDemo.App.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:WPFDemo.App">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
17
demo/WPFDemo/WPFDemo.App/App.xaml.cs
Normal file
17
demo/WPFDemo/WPFDemo.App/App.xaml.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
|
||||
namespace WPFDemo.App
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
}
|
||||
10
demo/WPFDemo/WPFDemo.App/AssemblyInfo.cs
Normal file
10
demo/WPFDemo/WPFDemo.App/AssemblyInfo.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
12
demo/WPFDemo/WPFDemo.App/MainWindow.xaml
Normal file
12
demo/WPFDemo/WPFDemo.App/MainWindow.xaml
Normal file
@@ -0,0 +1,12 @@
|
||||
<Window x:Class="WPFDemo.App.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:WPFDemo.App"
|
||||
mc:Ignorable="d"
|
||||
Title="MainWindow" Height="450" Width="800">
|
||||
<Grid>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
26
demo/WPFDemo/WPFDemo.App/MainWindow.xaml.cs
Normal file
26
demo/WPFDemo/WPFDemo.App/MainWindow.xaml.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace WPFDemo.App
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
88
demo/WPFDemo/WPFDemo.App/Program.cs
Normal file
88
demo/WPFDemo/WPFDemo.App/Program.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using dotnetCampus.Cli;
|
||||
using dotnetCampus.Configurations.Core;
|
||||
|
||||
using WPFDemo.Api.Startup;
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
using WPFDemo.App.StartupTaskFramework;
|
||||
using WPFDemo.Lib1.Startup;
|
||||
|
||||
namespace WPFDemo.App
|
||||
{
|
||||
class Program
|
||||
{
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var commandLine = CommandLine.Parse(args);
|
||||
|
||||
var app = new App();
|
||||
|
||||
//开始启动任务
|
||||
StartStartupTasks(commandLine);
|
||||
|
||||
app.Run();
|
||||
}
|
||||
|
||||
private static void StartStartupTasks(CommandLine commandLine)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
// 获取应用配置文件逻辑
|
||||
var configFilePath = "App.coin";
|
||||
var repo = ConfigurationFactory.FromFile(configFilePath);
|
||||
|
||||
var assemblyMetadataExporter = new AssemblyMetadataExporter(BuildStartupAssemblies());
|
||||
|
||||
var startupManager = new StartupManager(commandLine, repo, HandleShutdownError, new MainThreadDispatcher())
|
||||
.UseCriticalNodes
|
||||
(
|
||||
StartupNodes.Foundation,
|
||||
StartupNodes.CoreUI,
|
||||
StartupNodes.UI,
|
||||
StartupNodes.AppReady,
|
||||
StartupNodes.StartupCompleted
|
||||
)
|
||||
// 导出程序集的启动项
|
||||
.AddStartupTaskMetadataCollector(() =>
|
||||
assemblyMetadataExporter.ExportStartupTasks());
|
||||
startupManager.Run();
|
||||
});
|
||||
}
|
||||
|
||||
private static Assembly[] BuildStartupAssemblies()
|
||||
{
|
||||
// 初始化预编译收集的所有模块。
|
||||
return new Assembly[]
|
||||
{
|
||||
// WPFDemo.App
|
||||
typeof(Program).Assembly,
|
||||
// WPFDemo.Lib1
|
||||
typeof(Foo2Startup).Assembly,
|
||||
// WPFDemo.Api
|
||||
typeof(Foo1Startup).Assembly,
|
||||
};
|
||||
}
|
||||
|
||||
private static Task HandleShutdownError(Exception ex)
|
||||
{
|
||||
// 这是启动过程的异常,需要进行退出
|
||||
|
||||
#if DEBUG
|
||||
Debug.WriteLine("========== [初始化过程中出现致命错误,详情请查看异常信息] ==========");
|
||||
Debug.WriteLine(ex.ToString());
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Debugger.Break();
|
||||
}
|
||||
#endif
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
6
demo/WPFDemo/WPFDemo.App/Properties/AssemblyInfo.cs
Normal file
6
demo/WPFDemo/WPFDemo.App/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using dotnetCampus.Telescope;
|
||||
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
[assembly: MarkExport(typeof(StartupTask), typeof(StartupTaskAttribute))]
|
||||
8
demo/WPFDemo/WPFDemo.App/Properties/launchSettings.json
Normal file
8
demo/WPFDemo/WPFDemo.App/Properties/launchSettings.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"profiles": {
|
||||
"WPFDemo.App": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "-Name ApplicationStartupManager"
|
||||
}
|
||||
}
|
||||
}
|
||||
28
demo/WPFDemo/WPFDemo.App/Startup/BusinessStartup.cs
Normal file
28
demo/WPFDemo/WPFDemo.App/Startup/BusinessStartup.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
namespace WPFDemo.App.Startup
|
||||
{
|
||||
[StartupTask(BeforeTasks = StartupNodes.AppReady, AfterTasks = "MainWindowStartup", Scheduler = StartupScheduler.UIOnly)]
|
||||
internal class BusinessStartup : StartupTask
|
||||
{
|
||||
protected override Task RunAsync(StartupContext context)
|
||||
{
|
||||
if (Application.Current.MainWindow.Content is Grid grid)
|
||||
{
|
||||
grid.Children.Add(new Button()
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Bottom,
|
||||
Margin = new Thickness(10, 10, 10, 10),
|
||||
Content = "Click"
|
||||
});
|
||||
}
|
||||
|
||||
return CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
demo/WPFDemo/WPFDemo.App/Startup/MainWindowStartup.cs
Normal file
23
demo/WPFDemo/WPFDemo.App/Startup/MainWindowStartup.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
namespace WPFDemo.App.Startup
|
||||
{
|
||||
[StartupTask(BeforeTasks = StartupNodes.AppReady, AfterTasks = StartupNodes.UI, Scheduler = StartupScheduler.UIOnly)]
|
||||
internal class MainWindowStartup : StartupTask
|
||||
{
|
||||
protected override Task RunAsync(StartupContext context)
|
||||
{
|
||||
var mainWindow = new MainWindow();
|
||||
mainWindow.Show();
|
||||
|
||||
return CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
|
||||
namespace WPFDemo.App.StartupTaskFramework
|
||||
{
|
||||
// 因为没有在 WPFDemo.Api 引用 WPF 程序集,因此代码写在这里
|
||||
class MainThreadDispatcher : IMainThreadDispatcher
|
||||
{
|
||||
public async Task InvokeAsync(Action action)
|
||||
{
|
||||
await Application.Current.Dispatcher.InvokeAsync(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
22
demo/WPFDemo/WPFDemo.App/WPFDemo.App.csproj
Normal file
22
demo/WPFDemo/WPFDemo.App/WPFDemo.App.csproj
Normal file
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<StartupObject>WPFDemo.App.Program</StartupObject>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WPFDemo.Api\WPFDemo.Api.csproj" />
|
||||
<ProjectReference Include="..\WPFDemo.Lib1\WPFDemo.Lib1.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="dotnetCampus.CommandLine" Version="3.3.1-alpha03"/>
|
||||
<PackageReference Include="dotnetCampus.TelescopeSource" Version="1.0.0-alpha02" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
6
demo/WPFDemo/WPFDemo.Lib1/Properties/AssemblyInfo.cs
Normal file
6
demo/WPFDemo/WPFDemo.Lib1/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using dotnetCampus.Telescope;
|
||||
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
[assembly: MarkExport(typeof(StartupTask), typeof(StartupTaskAttribute))]
|
||||
16
demo/WPFDemo/WPFDemo.Lib1/Startup/Foo2Startup.cs
Normal file
16
demo/WPFDemo/WPFDemo.Lib1/Startup/Foo2Startup.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
namespace WPFDemo.Lib1.Startup
|
||||
{
|
||||
[StartupTask(BeforeTasks = StartupNodes.CoreUI, AfterTasks = StartupNodes.Foundation)]
|
||||
public class Foo2Startup : StartupTask
|
||||
{
|
||||
protected override Task RunAsync(StartupContext context)
|
||||
{
|
||||
context.Logger.LogInfo("Foo2 Startup");
|
||||
return base.RunAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
16
demo/WPFDemo/WPFDemo.Lib1/Startup/Foo3Startup.cs
Normal file
16
demo/WPFDemo/WPFDemo.Lib1/Startup/Foo3Startup.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
namespace WPFDemo.Lib1.Startup
|
||||
{
|
||||
[StartupTask(BeforeTasks = StartupNodes.CoreUI, AfterTaskList = new[] { nameof(WPFDemo.Lib1.Startup.Foo2Startup), "Foo1Startup" })]
|
||||
public class Foo3Startup : StartupTask
|
||||
{
|
||||
protected override Task RunAsync(StartupContext context)
|
||||
{
|
||||
context.Logger.LogInfo("Foo3 Startup");
|
||||
return base.RunAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
demo/WPFDemo/WPFDemo.Lib1/Startup/LibStartup.cs
Normal file
15
demo/WPFDemo/WPFDemo.Lib1/Startup/LibStartup.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using dotnetCampus.ApplicationStartupManager;
|
||||
using WPFDemo.Api.StartupTaskFramework;
|
||||
|
||||
namespace WPFDemo.Lib1.Startup
|
||||
{
|
||||
[StartupTask(BeforeTasks = StartupNodes.Foundation)]
|
||||
class LibStartup : StartupTask
|
||||
{
|
||||
protected override Task RunAsync(StartupContext context)
|
||||
{
|
||||
context.Logger.LogInfo("Lib Startup");
|
||||
return base.RunAsync(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
17
demo/WPFDemo/WPFDemo.Lib1/WPFDemo.Lib1.csproj
Normal file
17
demo/WPFDemo/WPFDemo.Lib1/WPFDemo.Lib1.csproj
Normal file
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WPFDemo.Api\WPFDemo.Api.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="dotnetCampus.TelescopeSource" Version="1.0.0-alpha02" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,12 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.31605.320
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.32014.148
|
||||
MinimumVisualStudioVersion = 15.0.26124.0
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5D196596-756D-45C2-8A05-C8E4AB8A36E6}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnetCampus.ApplicationStartupManager", "src\dotnetCampus.ApplicationStartupManager\dotnetCampus.ApplicationStartupManager.csproj", "{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "demo", "demo", "{A02845A0-C78A-407C-ACF2-529AE6600906}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WPFDemo.App", "demo\WPFDemo\WPFDemo.App\WPFDemo.App.csproj", "{32CDDF87-194D-4A6C-9DF5-B9D21A8F45AF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFDemo.Api", "demo\WPFDemo\WPFDemo.Api\WPFDemo.Api.csproj", "{68AD8EB7-A9A1-4EA7-A419-9BA1F74ACA32}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPFDemo.Lib1", "demo\WPFDemo\WPFDemo.Lib1\WPFDemo.Lib1.csproj", "{F4102A0A-E10A-462E-9AB1-0F80C83065D1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -17,12 +25,27 @@ Global
|
||||
{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{32CDDF87-194D-4A6C-9DF5-B9D21A8F45AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{32CDDF87-194D-4A6C-9DF5-B9D21A8F45AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{32CDDF87-194D-4A6C-9DF5-B9D21A8F45AF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{32CDDF87-194D-4A6C-9DF5-B9D21A8F45AF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{68AD8EB7-A9A1-4EA7-A419-9BA1F74ACA32}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{68AD8EB7-A9A1-4EA7-A419-9BA1F74ACA32}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{68AD8EB7-A9A1-4EA7-A419-9BA1F74ACA32}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{68AD8EB7-A9A1-4EA7-A419-9BA1F74ACA32}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F4102A0A-E10A-462E-9AB1-0F80C83065D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F4102A0A-E10A-462E-9AB1-0F80C83065D1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F4102A0A-E10A-462E-9AB1-0F80C83065D1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F4102A0A-E10A-462E-9AB1-0F80C83065D1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{F7ED61F4-920C-49EB-8DC1-74B2BE6AF272} = {5D196596-756D-45C2-8A05-C8E4AB8A36E6}
|
||||
{32CDDF87-194D-4A6C-9DF5-B9D21A8F45AF} = {A02845A0-C78A-407C-ACF2-529AE6600906}
|
||||
{68AD8EB7-A9A1-4EA7-A419-9BA1F74ACA32} = {A02845A0-C78A-407C-ACF2-529AE6600906}
|
||||
{F4102A0A-E10A-462E-9AB1-0F80C83065D1} = {A02845A0-C78A-407C-ACF2-529AE6600906}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {8AAD3A7E-EBB6-4125-9048-4CDE053D079B}
|
||||
|
||||
@@ -444,9 +444,9 @@ namespace dotnetCampus.ApplicationStartupManager
|
||||
private static string StartupTypeToKey(Type type)
|
||||
=> type.Name.Remove(type.Name.Length - "startup".Length);
|
||||
|
||||
internal virtual Task<string> ExecuteStartupTaskAsync(StartupTaskBase startupTask, IStartupContext context, bool uiOnly)
|
||||
protected internal virtual Task<string> ExecuteStartupTaskAsync(StartupTaskBase startupTask, IStartupContext context, bool uiOnly)
|
||||
{
|
||||
return startupTask.JoinAsync(context, uiOnly);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user