描述

当我们安装完 DotNetCore 3.0 版本的 SDK 后,我们就可以创建基于 DotNetCore 的 WPF 项目模板,通过如下 CLI
可以方便快捷的创建并运行我们的项目:
dotnet new wpf -n WpfApp cd WpfApp dotnet restore dotnet run
做过 WPF 开发的朋友都知道,这个项目模板肯定不符合我们的预期,我们希望我们的项目模板能够加入 MVVM 的默认代码段,并且能够和 DotNetCore
紧密合作,这样岂不是更加方便了吗? 所以本文使用 MVVM 的一种实现MvvmLightStd10 来教大家如何创建一个我们理想的项目模板。

操作

首先,我们基于 DotNetCore 3.0 创建一个原始的 WPF 项目模板,然后引用如下库:

* Microsoft.Extensions.DependencyInjection
* MvvmLightLibsStd10
可通过执行 cli 命令进行安装
dotnet add package Microsoft.Extensions.DependencyInjection dotnet add package
MvvmLightLibsStd10
注:因为我们使用了 DotNetCore,所以我们尽量让我们安装的第三方包是基于 .NET Standard 方式来实现。

然后,尝试修改我们的这个项目,把它改成我们以后期望创建的项目模板的样子。可以参考我的如下修改:

项目结构如下图所示:



其中,src\Models\DataItem.cs 的示例代码如下所示:
using System; using System.Collections.Generic; using System.Text; namespace
WpfApp.Models { public class DataItem { public string Title { get; private set;
} public DataItem(string title) { Title = title; } } }
src\Models\IDataService.cs 的示例代码如下所示:
using System; using System.Collections.Generic; using System.Text; namespace
WpfApp.Models { public interface IDataService { void GetData(Action<DataItem,
Exception> callback); } }
src\Models\DataService.cs 的示例代码如下所示:
using System; using System.Collections.Generic; using System.Text; namespace
WpfApp.Models { public class DataService : IDataService { public void
GetData(Action<DataItem, Exception> callback) { var item = new DataItem("Hello
.NET Core!"); callback(item, null); } } }
src\ViewModels\MainViewModel.cs 的示例代码如下所示:
using GalaSoft.MvvmLight; using WpfApp.Models; namespace WpfApp.ViewModels {
public class MainViewModel : ViewModelBase { private readonly IDataService
_dataService; private string _welcomeTitle; public string WelcomeTitle { get {
return _welcomeTitle; } set { Set(ref _welcomeTitle, value); } } public
MainViewModel(IDataService dataService) { _dataService = dataService;
_dataService.GetData( (item, error) => { if (error != null) { return; }
WelcomeTitle = item.Title; }); } } }
src\Views\MainView.xaml 的示例代码如下所示:
<Window x:Class="WpfApp.Views.MainView"
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:local="clr-namespace:WpfApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow" Width="800" Height="450" mc:Ignorable="d"> <Grid> <Label
HorizontalAlignment="Center" VerticalAlignment="Center" Content="{Binding
WelcomeTitle}" FontSize="40" /> </Grid> </Window>
src\Views\MainView.xaml.cs 的示例代码如下所示:
using System.Windows; using WpfApp.ViewModels; namespace WpfApp.Views { public
partial class MainView : Window { public MainView(MainViewModel vm) {
InitializeComponent(); this.DataContext = vm; } } }
src\App.xaml 的示例代码如下所示:
<Application x:Class="WpfApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApp" />
src\App.xaml.cs 的示例代码如下所示:
using Microsoft.Extensions.DependencyInjection; using System.Windows; using
WpfApp.Models; using WpfApp.ViewModels; using WpfApp.Views; namespace WpfApp {
public partial class App : Application { public ServiceProvider ServiceProvider
{ get; private set; } protected override void OnStartup(StartupEventArgs e) {
base.OnStartup(e); var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection); ServiceProvider =
serviceCollection.BuildServiceProvider(); var mainWindow =
ServiceProvider.GetRequiredService<MainView>(); mainWindow.Show(); } private
void ConfigureServices(ServiceCollection services) {
services.AddTransient<MainView>(); services.AddTransient<MainViewModel>();
services.AddScoped<IDataService, DataService>(); } } }
修改完毕后尝试编译运行我们的项目,确保可以正常编译运行。

之后,在我们的项目根目录 src 下新建一个 .template.config 文件夹,然后在里面新建一个 template.json
文件,进行如下示例配置:
{ "$schema": "http://json.schemastore.org/template", "author": "hippiezhou
<hippiezhou@outlook.com>", "classifications": ["wpf", "mvvmlight", "Dependency
Injection"], "name": "wpf mvvmlight: use dotnetcore to create wpf with
mvvmlight.", "tags": { "language": "C#", "type": "project" }, "identity":
"wpf.mvvmlight", "shortName": "wpf-mvvmlight", "sourceName": "wpf.mvvmlight",
"preferNameDirectory": true }
最后,打开我们的终端,将目录切换至当前项目目录下(就是 .template.config 所在的目录),然后执行下述安装操作
dotnet new -i C:\Users\hippieZhou\Desktop\helloworld\wpfapp
此时,我们的项目模板会被打包到 DotNetCore 的 CLI 中,如下图所示:



同时,在 C:\Users\hippieZhou.templateengine\dotnetcli\v3.0.100-preview3-010431
目录下的以templatecache.json 结尾的 JSON 文件内容也会发生修改,会在 TemplateInfo 结点下新增一个如下的节点内容:
{ "ConfigMountPointId": "f3861181-7a43-4fc5-ab1c-12d95e734c0a", "Author":
"hippiezhou <hippiezhou@outlook.com>", "Classifications": [ "wpf", "mvvmlight",
"Dependency Injection" ], "DefaultName": null, "Description": "", "Identity":
"wpf.mvvmlight", "GeneratorId": "0c434df7-e2cb-4dee-b216-d7c58c8eb4b3",
"GroupIdentity": "", "Precedence": 0, "Name": "wpf mvvmlight: use dotnetcore to
create wpf with mvvmlight.", "ShortNameList": [ "wpf-mvvmlight" ], "Tags": {
"language": { "Description": null, "ChoicesAndDescriptions": { "C#": "" },
"DefaultValue": "C#" }, "type": { "Description": null,
"ChoicesAndDescriptions": { "project": "" }, "DefaultValue": "project" } },
"CacheParameters": { "name": { "DataType": "string", "DefaultValue": null,
"Description": "The default name symbol" } }, "ConfigPlace":
"/.template.config/template.json", "LocaleConfigMountPointId":
"00000000-0000-0000-0000-000000000000", "LocaleConfigPlace": null,
"HostConfigMountPointId": "00000000-0000-0000-0000-000000000000",
"HostConfigPlace": null, "ThirdPartyNotices": null, "BaselineInfo": {},
"HasScriptRunningPostActions": false, "ConfigTimestampUtc": null },
注:如果后期我们不慎将我们的模板删除了,我们通过删除掉这两个文件里面对应的模板节点就可以在 CLI 中取消应用了。

我们可以使用下述操作进行测试一下:
# 使用我们自定义的项目模板,创建 wpf 项目 dotnet new wpf-mvvmlight -n test cd test dotnet
restore dotnet run
如果不出意外的话,我们就可以看到这个项目的代码段和我们自定义的模板代码段是一样的。

如果卸载我们的项目模板可以使用如下命令:
dotnet new -u C:\Users\hippieZhou\Desktop\helloworld\wpfapp
注:我们需要确保我们的自定义模板不能丢失,要不然到时候就卸载就麻烦了(至少目前看来是这样的)。

关于如何将我们的自定义模板可以上传到 NuGet 供别人下载使用,这里就不做介绍了,具体操作可参考园里介绍如何在 DotNetCore MVC
中打造自己的项目模板方法是一样的。我在本文中的创建的代码模板也不会提交上去,还是等着 MVVMLight 的原作者Laurent Bugnion
来操刀会好一些。

总结

本文介绍了如何通过 DotNet CLI 来创建自定义的 WPF 项目模板。在实际的使用过程中,CLI
的功能和支持的参数会更多,所以感兴趣的朋友可以自行研究。

相关参考

* how-to-create-a-dot-net-new-project-template-in-dot-net-core
<https://pioneercode.com/post/how-to-create-a-dot-net-new-project-template-in-dot-net-core>
* 打造自己的.NET Core项目模板 <https://www.cnblogs.com/catcher1994/p/10061470.html>

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信