get plugin system working

This commit is contained in:
TheXamlGuy
2024-01-04 20:53:49 +00:00
parent da8af59391
commit d45076f2a9
24 changed files with 219 additions and 55 deletions
@@ -0,0 +1,11 @@
using Microsoft.Extensions.DependencyInjection;
namespace Hyperbar.Desktop.Contextual;
public class ContextualCommandBuilder : ICommandBuilder
{
public void Create(IServiceCollection services)
{
services.AddCommandTemplate<ContextualCommandViewModel, ContextualCommandView>();
}
}
@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Hyperbar.Desktop.ContextualCommandView"
x:Class="Hyperbar.Desktop.Contextual.ContextualCommandView"
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="using:Hyperbar.Desktop"
xmlns:local="using:Hyperbar.Desktop.Contextual"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<Grid>
<Button />
<Button Content="This is a test" />
</Grid>
</Page>
@@ -1,6 +1,6 @@
using Microsoft.UI.Xaml.Controls;
namespace Hyperbar.Desktop;
namespace Hyperbar.Desktop.Contextual;
public sealed partial class ContextualCommandView : Page
{
@@ -1,6 +1,7 @@
namespace Hyperbar.Desktop;
namespace Hyperbar.Desktop.Contextual;
public class ContextualCommandViewModel :
ICommandViewModel,
ITemplatedViewModel
{
public ContextualCommandViewModel(ITemplateFactory templateFactory)
@@ -9,4 +10,4 @@ public class ContextualCommandViewModel :
}
public ITemplateFactory TemplateFactory { get; }
}
}
@@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<RootNamespace>Hyperbar.Desktop.Contextual</RootNamespace>
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
<UseWinUI>true</UseWinUI>
<UseRidGraph>true</UseRidGraph>
</PropertyGroup>
<ItemGroup>
<None Remove="ContextualCommandView.xaml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.231202003-experimental1" />
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.25936-preview" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
</ItemGroup>
<ItemGroup>
<Page Update="ContextualCommandView.xaml">
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
</Project>
+30 -9
View File
@@ -1,8 +1,10 @@
using Hyperbar.Desktop.Controls;
using Hyperbar.Desktop.Contextual;
using Hyperbar.Desktop.Controls;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.UI.Xaml;
using System;
using System.Collections.Generic;
namespace Hyperbar.Desktop;
@@ -17,18 +19,37 @@ public partial class App :
IHost? host = Host.CreateDefaultBuilder()
.UseContentRoot(AppContext.BaseDirectory)
.ConfigureServices(args =>
.ConfigureServices(services =>
{
args.AddTransient<IInitializer, AppInitializer>();
args.AddTransient<DesktopFlyout>();
services.AddHostedService<AppService>();
args.AddTransient<ITemplateFactory, TemplateFactory>();
args.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
services.AddTransient<IInitializer, AppInitializer>();
services.AddTransient<DesktopFlyout>();
args.AddDataTemplate<CommandViewModel, CommandView>("Commands");
args.AddDataTemplate<ContextualCommandViewModel, ContextualCommandView>();
services.AddTransient<ITemplateFactory, TemplateFactory>();
services.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
args.AddHostedService<AppService>();
services.AddDataTemplate<CommandViewModel, CommandView>("Commands");
// Commands
services.AddSomething<ContextualCommandBuilder>();
services.AddTransient(provider =>
{
IEnumerable<ICommandViewModel> Resolve(IServiceProvider services)
{
foreach (ICommandContext commandContext in services.GetServices<ICommandContext>())
{
if (commandContext.ServiceProvider.GetService<ICommandViewModel>() is
ICommandViewModel commandViewModel)
{
yield return commandViewModel;
}
}
}
return Resolve(provider);
});
})
.Build();
+1
View File
@@ -41,6 +41,7 @@
</Page>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Hyperbar.Desktop.Contextual\Hyperbar.Desktop.Contextual.csproj" />
<ProjectReference Include="..\Hyperbar.Desktop.Controls\Hyperbar.Desktop.Controls.csproj" />
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
</ItemGroup>
@@ -0,0 +1,26 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Hyperbar.Desktop
{
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddSomething<TCommandBuilder>(this IServiceCollection services)
where TCommandBuilder :
ICommandBuilder, new()
{
TCommandBuilder builder = new();
IHost? host = new HostBuilder()
.ConfigureServices(services =>
{
services.AddTransient<ITemplateFactory, TemplateFactory>();
services.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
builder.Create(services);
}).Build();
services.AddTransient<ICommandContext>(provider => new CommandContext(host.Services));
return services;
}
}
}
@@ -2,6 +2,7 @@
namespace Hyperbar.Desktop
{
public interface ITemplateGeneratorFactory
{
DataTemplate Create();
@@ -9,10 +9,10 @@ public class TemplateGeneratorFactory :
public DataTemplate Create()
{
string xamlString = @"
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:desktop='using:Hyperbar.Desktop'>
<desktop:TemplateGeneratorControl />
</DataTemplate>";
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:desktop='using:Hyperbar.Desktop'>
<desktop:TemplateGeneratorControl />
</DataTemplate>";
return (DataTemplate)XamlReader.Load(xamlString);
}
+10 -9
View File
@@ -1,20 +1,21 @@
namespace Hyperbar.Desktop;
using System.Collections;
using System.Collections.Generic;
namespace Hyperbar.Desktop;
public partial class CommandViewModel :
ObservableCollectionViewModel,
ITemplatedViewModel
{
public CommandViewModel(ITemplateFactory templateFactory)
public CommandViewModel(ITemplateFactory templateFactory,
IEnumerable<ICommandViewModel> commands)
{
TemplateFactory = templateFactory;
this.Add(new ContextualCommandViewModel(templateFactory));
this.Add(new ContextualCommandViewModel(templateFactory));
this.Add(new ContextualCommandViewModel(templateFactory));
this.Add(new ContextualCommandViewModel(templateFactory));
this.Add(new ContextualCommandViewModel(templateFactory));
var d = Items;
foreach (var command in commands)
{
this.Add(command);
}
}
public ITemplateFactory TemplateFactory { get; }
+18
View File
@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbar.Desktop.Win32", "H
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbar", "Hyperbar\Hyperbar.csproj", "{E5795878-C7E3-4386-86FA-33681BCF8D5B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hyperbar.Desktop.Contextual", "Hyperbar.Desktop.Contextual\Hyperbar.Desktop.Contextual.csproj", "{C32D4073-2A9B-4257-8895-09951FAD8E7A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -95,6 +97,22 @@ Global
{E5795878-C7E3-4386-86FA-33681BCF8D5B}.Release|x64.Build.0 = Release|Any CPU
{E5795878-C7E3-4386-86FA-33681BCF8D5B}.Release|x86.ActiveCfg = Release|Any CPU
{E5795878-C7E3-4386-86FA-33681BCF8D5B}.Release|x86.Build.0 = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|ARM64.Build.0 = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|x64.ActiveCfg = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|x64.Build.0 = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|x86.ActiveCfg = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Debug|x86.Build.0 = Debug|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|Any CPU.Build.0 = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|ARM64.ActiveCfg = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|ARM64.Build.0 = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|x64.ActiveCfg = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|x64.Build.0 = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|x86.ActiveCfg = Release|Any CPU
{C32D4073-2A9B-4257-8895-09951FAD8E7A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
-27
View File
@@ -1,27 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
namespace Hyperbar;
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddDataTemplate<TData, TTemplate>(this IServiceCollection services,
object? key = null)
{
Type dataType = typeof(TData);
Type templateType = typeof(TTemplate);
key ??= dataType.Name;
services.AddKeyedTransient(dataType, key);
services.AddKeyedTransient(templateType, key);
services.AddTransient<IDataTemplateDescriptor>(provider => new DataTemplateDescriptor
{
DataType = dataType,
TemplateType = templateType,
Key = key
});
return services;
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace Hyperbar;
public class CommandContext(IServiceProvider serviceProvider) :
ICommandContext
{
public IServiceProvider ServiceProvider => serviceProvider;
}
+8
View File
@@ -0,0 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
namespace Hyperbar;
public interface ICommandBuilder
{
void Create(IServiceCollection services);
}
+6
View File
@@ -0,0 +1,6 @@
namespace Hyperbar;
public interface ICommandContext
{
IServiceProvider ServiceProvider { get; }
}
+7
View File
@@ -0,0 +1,7 @@
namespace Hyperbar;
public interface ICommandViewModel
{
}
@@ -0,0 +1,53 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace Hyperbar;
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddCommandTemplate<TCommand, TCommandTemplate>(this IServiceCollection services)
where TCommand :
ICommandViewModel
{
Type dataType = typeof(TCommand);
Type templateType = typeof(TCommandTemplate);
var key = dataType.Name;
services.AddTransient(typeof(ICommandViewModel), dataType);
services.AddTransient(templateType);
services.AddKeyedTransient(typeof(ICommandViewModel), key, dataType);
services.AddKeyedTransient(templateType, key);
services.AddTransient<IDataTemplateDescriptor>(provider => new DataTemplateDescriptor
{
DataType = dataType,
TemplateType = templateType,
Key = key
});
return services;
}
public static IServiceCollection AddDataTemplate<TData, TTemplate>(this IServiceCollection services,
object? key = null)
{
Type dataType = typeof(TData);
Type templateType = typeof(TTemplate);
key ??= dataType.Name;
services.AddKeyedTransient(dataType, key);
services.AddKeyedTransient(templateType, key);
services.AddTransient<IDataTemplateDescriptor>(provider => new DataTemplateDescriptor
{
DataType = dataType,
TemplateType = templateType,
Key = key
});
return services;
}
}