get plugin system working
This commit is contained in:
@@ -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>();
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -1,15 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<Page
|
<Page
|
||||||
x:Class="Hyperbar.Desktop.ContextualCommandView"
|
x:Class="Hyperbar.Desktop.Contextual.ContextualCommandView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
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"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Button />
|
<Button Content="This is a test" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
|
||||||
namespace Hyperbar.Desktop;
|
namespace Hyperbar.Desktop.Contextual;
|
||||||
|
|
||||||
public sealed partial class ContextualCommandView : Page
|
public sealed partial class ContextualCommandView : Page
|
||||||
{
|
{
|
||||||
+3
-2
@@ -1,6 +1,7 @@
|
|||||||
namespace Hyperbar.Desktop;
|
namespace Hyperbar.Desktop.Contextual;
|
||||||
|
|
||||||
public class ContextualCommandViewModel :
|
public class ContextualCommandViewModel :
|
||||||
|
ICommandViewModel,
|
||||||
ITemplatedViewModel
|
ITemplatedViewModel
|
||||||
{
|
{
|
||||||
public ContextualCommandViewModel(ITemplateFactory templateFactory)
|
public ContextualCommandViewModel(ITemplateFactory templateFactory)
|
||||||
@@ -9,4 +10,4 @@ public class ContextualCommandViewModel :
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ITemplateFactory TemplateFactory { get; }
|
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>
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
using Hyperbar.Desktop.Controls;
|
using Hyperbar.Desktop.Contextual;
|
||||||
|
using Hyperbar.Desktop.Controls;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Hyperbar.Desktop;
|
namespace Hyperbar.Desktop;
|
||||||
|
|
||||||
@@ -17,18 +19,37 @@ public partial class App :
|
|||||||
|
|
||||||
IHost? host = Host.CreateDefaultBuilder()
|
IHost? host = Host.CreateDefaultBuilder()
|
||||||
.UseContentRoot(AppContext.BaseDirectory)
|
.UseContentRoot(AppContext.BaseDirectory)
|
||||||
.ConfigureServices(args =>
|
.ConfigureServices(services =>
|
||||||
{
|
{
|
||||||
args.AddTransient<IInitializer, AppInitializer>();
|
services.AddHostedService<AppService>();
|
||||||
args.AddTransient<DesktopFlyout>();
|
|
||||||
|
|
||||||
args.AddTransient<ITemplateFactory, TemplateFactory>();
|
services.AddTransient<IInitializer, AppInitializer>();
|
||||||
args.AddTransient<ITemplateGeneratorFactory, TemplateGeneratorFactory>();
|
services.AddTransient<DesktopFlyout>();
|
||||||
|
|
||||||
args.AddDataTemplate<CommandViewModel, CommandView>("Commands");
|
services.AddTransient<ITemplateFactory, TemplateFactory>();
|
||||||
args.AddDataTemplate<ContextualCommandViewModel, ContextualCommandView>();
|
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();
|
.Build();
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Hyperbar.Desktop.Contextual\Hyperbar.Desktop.Contextual.csproj" />
|
||||||
<ProjectReference Include="..\Hyperbar.Desktop.Controls\Hyperbar.Desktop.Controls.csproj" />
|
<ProjectReference Include="..\Hyperbar.Desktop.Controls\Hyperbar.Desktop.Controls.csproj" />
|
||||||
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
|
<ProjectReference Include="..\Hyperbar\Hyperbar.csproj" />
|
||||||
</ItemGroup>
|
</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
|
namespace Hyperbar.Desktop
|
||||||
{
|
{
|
||||||
|
|
||||||
public interface ITemplateGeneratorFactory
|
public interface ITemplateGeneratorFactory
|
||||||
{
|
{
|
||||||
DataTemplate Create();
|
DataTemplate Create();
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ public class TemplateGeneratorFactory :
|
|||||||
public DataTemplate Create()
|
public DataTemplate Create()
|
||||||
{
|
{
|
||||||
string xamlString = @"
|
string xamlString = @"
|
||||||
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
|
<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
|
||||||
xmlns:desktop='using:Hyperbar.Desktop'>
|
xmlns:desktop='using:Hyperbar.Desktop'>
|
||||||
<desktop:TemplateGeneratorControl />
|
<desktop:TemplateGeneratorControl />
|
||||||
</DataTemplate>";
|
</DataTemplate>";
|
||||||
|
|
||||||
return (DataTemplate)XamlReader.Load(xamlString);
|
return (DataTemplate)XamlReader.Load(xamlString);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
namespace Hyperbar.Desktop;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Hyperbar.Desktop;
|
||||||
|
|
||||||
public partial class CommandViewModel :
|
public partial class CommandViewModel :
|
||||||
ObservableCollectionViewModel,
|
ObservableCollectionViewModel,
|
||||||
ITemplatedViewModel
|
ITemplatedViewModel
|
||||||
{
|
{
|
||||||
public CommandViewModel(ITemplateFactory templateFactory)
|
public CommandViewModel(ITemplateFactory templateFactory,
|
||||||
|
IEnumerable<ICommandViewModel> commands)
|
||||||
{
|
{
|
||||||
TemplateFactory = templateFactory;
|
TemplateFactory = templateFactory;
|
||||||
|
|
||||||
this.Add(new ContextualCommandViewModel(templateFactory));
|
foreach (var command in commands)
|
||||||
this.Add(new ContextualCommandViewModel(templateFactory));
|
{
|
||||||
this.Add(new ContextualCommandViewModel(templateFactory));
|
this.Add(command);
|
||||||
this.Add(new ContextualCommandViewModel(templateFactory));
|
}
|
||||||
this.Add(new ContextualCommandViewModel(templateFactory));
|
|
||||||
|
|
||||||
var d = Items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITemplateFactory TemplateFactory { get; }
|
public ITemplateFactory TemplateFactory { get; }
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbar.Desktop.Win32", "H
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbar", "Hyperbar\Hyperbar.csproj", "{E5795878-C7E3-4386-86FA-33681BCF8D5B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hyperbar", "Hyperbar\Hyperbar.csproj", "{E5795878-C7E3-4386-86FA-33681BCF8D5B}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hyperbar.Desktop.Contextual", "Hyperbar.Desktop.Contextual\Hyperbar.Desktop.Contextual.csproj", "{C32D4073-2A9B-4257-8895-09951FAD8E7A}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
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|x64.Build.0 = Release|Any CPU
|
||||||
{E5795878-C7E3-4386-86FA-33681BCF8D5B}.Release|x86.ActiveCfg = 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
|
{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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public class CommandContext(IServiceProvider serviceProvider) :
|
||||||
|
ICommandContext
|
||||||
|
{
|
||||||
|
public IServiceProvider ServiceProvider => serviceProvider;
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface ICommandBuilder
|
||||||
|
{
|
||||||
|
void Create(IServiceCollection services);
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
namespace Hyperbar;
|
||||||
|
|
||||||
|
public interface ICommandContext
|
||||||
|
{
|
||||||
|
IServiceProvider ServiceProvider { get; }
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user