diff --git a/Pure.DI.sln b/Pure.DI.sln index d96ded25e..db32b5226 100644 --- a/Pure.DI.sln +++ b/Pure.DI.sln @@ -98,6 +98,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeatherForecast", "samples\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalWebAPI", "samples\MinimalWebAPI\MinimalWebAPI.csproj", "{60F18CFA-957B-488F-8292-467D92C17267}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SingleRootAvaloniaApp", "samples\SingleRootAvaloniaApp\SingleRootAvaloniaApp.csproj", "{7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -200,6 +202,10 @@ Global {60F18CFA-957B-488F-8292-467D92C17267}.Debug|Any CPU.Build.0 = Debug|Any CPU {60F18CFA-957B-488F-8292-467D92C17267}.Release|Any CPU.ActiveCfg = Release|Any CPU {60F18CFA-957B-488F-8292-467D92C17267}.Release|Any CPU.Build.0 = Release|Any CPU + {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {7C9E056B-CBA9-4548-9CDB-C5CE03C491B0} = {8163CDD7-7018-4301-A984-803C3807A6A6} @@ -225,5 +231,6 @@ Global {D1C043C4-ED8F-45C5-8077-EF10AA71B951} = {FA80D231-C641-4A49-99C6-0C065D818B07} {9A3E2271-3090-4BCE-BB48-6C0724CFBE44} = {FA80D231-C641-4A49-99C6-0C065D818B07} {60F18CFA-957B-488F-8292-467D92C17267} = {FA80D231-C641-4A49-99C6-0C065D818B07} + {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8} = {FA80D231-C641-4A49-99C6-0C065D818B07} EndGlobalSection EndGlobal diff --git a/samples/Clock/Clock.csproj b/samples/Clock/Clock.csproj index f546b718f..bd56f18c1 100644 --- a/samples/Clock/Clock.csproj +++ b/samples/Clock/Clock.csproj @@ -12,6 +12,7 @@ + diff --git a/samples/SingleRootAvaloniaApp/App.axaml b/samples/SingleRootAvaloniaApp/App.axaml new file mode 100644 index 000000000..f0c118e0b --- /dev/null +++ b/samples/SingleRootAvaloniaApp/App.axaml @@ -0,0 +1,13 @@ + + + + + + + + + \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/App.axaml.cs b/samples/SingleRootAvaloniaApp/App.axaml.cs new file mode 100644 index 000000000..4cdfe7e89 --- /dev/null +++ b/samples/SingleRootAvaloniaApp/App.axaml.cs @@ -0,0 +1,24 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +namespace AvaloniaApp; + +public class App : Application +{ + public override void Initialize() => AvaloniaXamlLoader.Load(this); + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop + && Resources["Composition"] is Composition composition) + { + // Assignment of the main window + desktop.MainWindow = composition.App.MainWindow; + // Handles disposables + desktop.Exit += (_, _) => composition.Dispose(); + } + + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/AppDataContext.cs b/samples/SingleRootAvaloniaApp/AppDataContext.cs new file mode 100644 index 000000000..6c78f3270 --- /dev/null +++ b/samples/SingleRootAvaloniaApp/AppDataContext.cs @@ -0,0 +1,13 @@ +namespace AvaloniaApp; + +using Clock.ViewModels; +using Views; + +internal class AppDataContext( + Lazy mainWindow, + IClockViewModel clockViewModel) +{ + public MainWindow MainWindow => mainWindow.Value; + + public IClockViewModel ClockViewModel => clockViewModel; +} \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/Assets/avalonia-logo.ico b/samples/SingleRootAvaloniaApp/Assets/avalonia-logo.ico new file mode 100644 index 000000000..da8d49ff9 Binary files /dev/null and b/samples/SingleRootAvaloniaApp/Assets/avalonia-logo.ico differ diff --git a/samples/SingleRootAvaloniaApp/Composition.cs b/samples/SingleRootAvaloniaApp/Composition.cs new file mode 100644 index 000000000..8a777d627 --- /dev/null +++ b/samples/SingleRootAvaloniaApp/Composition.cs @@ -0,0 +1,31 @@ +// ReSharper disable UnusedMember.Local +// ReSharper disable UnusedMember.Global +// ReSharper disable RedundantNameQualifier +// ReSharper disable ArrangeTypeMemberModifiers +namespace AvaloniaApp; + +using Clock.Models; +using Clock.ViewModels; +using Pure.DI; +using static Pure.DI.Lifetime; + +internal partial class Composition +{ + void Setup() => DI.Setup(nameof(Composition)) + // A single compositional root for the application + .Root("App") + + .Bind().As(Singleton).To() + + // View Models + .Bind().To() + + // Models + .Bind().To>() + .Bind().To(_ => TimeSpan.FromSeconds(1)) + .Bind().As(Singleton).To() + .Bind().As(PerBlock).To() + + // Infrastructure + .Bind().To(); +} \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/Dispatcher.cs b/samples/SingleRootAvaloniaApp/Dispatcher.cs new file mode 100644 index 000000000..461105620 --- /dev/null +++ b/samples/SingleRootAvaloniaApp/Dispatcher.cs @@ -0,0 +1,10 @@ +namespace AvaloniaApp; + +using Clock.ViewModels; + +// ReSharper disable once ClassNeverInstantiated.Global +internal class Dispatcher: IDispatcher +{ + public void Dispatch(Action action) => + Avalonia.Threading.Dispatcher.UIThread.Post(action); +} \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/Program.cs b/samples/SingleRootAvaloniaApp/Program.cs new file mode 100644 index 000000000..cb98e4bfc --- /dev/null +++ b/samples/SingleRootAvaloniaApp/Program.cs @@ -0,0 +1,21 @@ +using Avalonia; +// ReSharper disable ClassNeverInstantiated.Global + +namespace AvaloniaApp; + +public class Program +{ + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + private static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); +} \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/SingleRootAvaloniaApp.csproj b/samples/SingleRootAvaloniaApp/SingleRootAvaloniaApp.csproj new file mode 100644 index 000000000..976274dd3 --- /dev/null +++ b/samples/SingleRootAvaloniaApp/SingleRootAvaloniaApp.csproj @@ -0,0 +1,26 @@ + + + + $(BaseTargetFramework) + WinExe + true + app.manifest + true + NU1801 + AvaloniaApp + + + + + + + + + + + + + + + + diff --git a/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml b/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml new file mode 100644 index 000000000..a2dee47e0 --- /dev/null +++ b/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml.cs b/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml.cs new file mode 100644 index 000000000..ed518af5e --- /dev/null +++ b/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml.cs @@ -0,0 +1,9 @@ +using Avalonia.Controls; + +namespace AvaloniaApp.Views; + +// ReSharper disable once ClassNeverInstantiated.Global +public partial class MainWindow : Window +{ + public MainWindow() => InitializeComponent(); +} \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/app.manifest b/samples/SingleRootAvaloniaApp/app.manifest new file mode 100644 index 000000000..0c5b544f0 --- /dev/null +++ b/samples/SingleRootAvaloniaApp/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + +