From 1f379a5e160ccac1bcc1497cac51d55b89cfe70a Mon Sep 17 00:00:00 2001 From: Nikolay Pianikov Date: Tue, 17 Sep 2024 12:12:38 +0300 Subject: [PATCH] Improved Avalonia examples --- Pure.DI.sln | 7 ++ readme/Avalonia.md | 76 ++++++++++++++++--- readme/AvaloniaPageTemplate.md | 76 ++++++++++++++++--- readme/BlazorServerApp.md | 5 +- readme/BlazorServerAppPageTemplate.md | 3 + readme/BlazorWebAssemblyApp.md | 5 +- readme/BlazorWebAssemblyAppPageTemplate.md | 3 + readme/Console.md | 4 + readme/ConsolePageTemplate.md | 4 + readme/GrpcService.md | 5 +- readme/GrpcServicePageTemplate.md | 3 + readme/Maui.md | 5 +- readme/MauiPageTemplate.md | 3 + readme/MinimalWebAPI.md | 5 +- readme/MinimalWebAPIPageTemplate.md | 3 + readme/WebAPI.md | 5 +- readme/WebAPIPageTemplate.md | 3 + readme/WebApp.md | 5 +- readme/WebAppPageTemplate.md | 3 + readme/WinFormsApp.md | 3 + readme/WinFormsAppNetCore.md | 3 + readme/WinFormsAppNetCorePageTemplate.md | 3 + readme/WinFormsAppPageTemplate.md | 3 + readme/Wpf.md | 3 + readme/WpfPageTemplate.md | 3 + samples/AvaloniaApp/App.axaml | 14 +++- samples/AvaloniaApp/Views/MainWindow.axaml | 4 +- samples/AvaloniaSimpleApp/App.axaml | 17 +++++ samples/AvaloniaSimpleApp/App.axaml.cs | 24 ++++++ .../AvaloniaSimpleApp.csproj | 21 +++++ samples/AvaloniaSimpleApp/BusinessService.cs | 11 +++ samples/AvaloniaSimpleApp/Composition.cs | 15 ++++ samples/AvaloniaSimpleApp/IBusinessService.cs | 6 ++ samples/AvaloniaSimpleApp/IMainViewModel.cs | 8 ++ samples/AvaloniaSimpleApp/IRepository.cs | 6 ++ samples/AvaloniaSimpleApp/MainViewModel.cs | 9 +++ samples/AvaloniaSimpleApp/MainWindow.axaml | 11 +++ samples/AvaloniaSimpleApp/MainWindow.axaml.cs | 11 +++ samples/AvaloniaSimpleApp/Program.cs | 21 +++++ samples/AvaloniaSimpleApp/Repository.cs | 8 ++ samples/AvaloniaSimpleApp/app.manifest | 18 +++++ samples/SingleRootAvaloniaApp/App.axaml | 11 ++- .../Views/MainWindow.axaml | 4 +- 43 files changed, 420 insertions(+), 40 deletions(-) create mode 100644 samples/AvaloniaSimpleApp/App.axaml create mode 100644 samples/AvaloniaSimpleApp/App.axaml.cs create mode 100644 samples/AvaloniaSimpleApp/AvaloniaSimpleApp.csproj create mode 100644 samples/AvaloniaSimpleApp/BusinessService.cs create mode 100644 samples/AvaloniaSimpleApp/Composition.cs create mode 100644 samples/AvaloniaSimpleApp/IBusinessService.cs create mode 100644 samples/AvaloniaSimpleApp/IMainViewModel.cs create mode 100644 samples/AvaloniaSimpleApp/IRepository.cs create mode 100644 samples/AvaloniaSimpleApp/MainViewModel.cs create mode 100644 samples/AvaloniaSimpleApp/MainWindow.axaml create mode 100644 samples/AvaloniaSimpleApp/MainWindow.axaml.cs create mode 100644 samples/AvaloniaSimpleApp/Program.cs create mode 100644 samples/AvaloniaSimpleApp/Repository.cs create mode 100644 samples/AvaloniaSimpleApp/app.manifest diff --git a/Pure.DI.sln b/Pure.DI.sln index 89ede7ec5..f764dae56 100644 --- a/Pure.DI.sln +++ b/Pure.DI.sln @@ -105,6 +105,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pure.DI.Abstractions", "src EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Pure.DI.Example", "tests\Pure.DI.Example\Pure.DI.Example.csproj", "{9D043E3D-878F-4D64-A689-7BE16A25842A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AvaloniaSimpleApp", "samples\AvaloniaSimpleApp\AvaloniaSimpleApp.csproj", "{29F9986B-4B32-4C30-AECA-D68EAB4EA9CB}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -219,6 +221,10 @@ Global {9D043E3D-878F-4D64-A689-7BE16A25842A}.Debug|Any CPU.Build.0 = Debug|Any CPU {9D043E3D-878F-4D64-A689-7BE16A25842A}.Release|Any CPU.ActiveCfg = Release|Any CPU {9D043E3D-878F-4D64-A689-7BE16A25842A}.Release|Any CPU.Build.0 = Release|Any CPU + {29F9986B-4B32-4C30-AECA-D68EAB4EA9CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29F9986B-4B32-4C30-AECA-D68EAB4EA9CB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29F9986B-4B32-4C30-AECA-D68EAB4EA9CB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29F9986B-4B32-4C30-AECA-D68EAB4EA9CB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {7C9E056B-CBA9-4548-9CDB-C5CE03C491B0} = {8163CDD7-7018-4301-A984-803C3807A6A6} @@ -247,5 +253,6 @@ Global {7FCFD4F6-AFB8-479C-A103-AEBC2FC282A8} = {FA80D231-C641-4A49-99C6-0C065D818B07} {136A2850-FDA0-4CDB-A798-21C4B4A01974} = {8163CDD7-7018-4301-A984-803C3807A6A6} {9D043E3D-878F-4D64-A689-7BE16A25842A} = {9DF1D09E-863F-4800-9E28-954440EE1601} + {29F9986B-4B32-4C30-AECA-D68EAB4EA9CB} = {FA80D231-C641-4A49-99C6-0C065D818B07} EndGlobalSection EndGlobal diff --git a/readme/Avalonia.md b/readme/Avalonia.md index d92d12bc9..d36ac3729 100644 --- a/readme/Avalonia.md +++ b/readme/Avalonia.md @@ -7,9 +7,12 @@ This example demonstrates the creation of a [Avalonia](https://avaloniaui.net/) > [!NOTE] > [Another example](samples/SingleRootAvaloniaApp) with Avalonia shows how to create an application with a single composition root. -The definition of the composition is in [Composition.cs](/samples/AvaloniaApp/Composition.cs). You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: +The definition of the composition is in [Composition.cs](/samples/AvaloniaApp/Composition.cs). This class setups how the composition of objects will be created for the application. You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() @@ -32,24 +35,46 @@ internal partial class Composition } ``` +Advantages over classical DI container libraries: +- No performance impact or side effects when creating composition of objects. +- All logic for analyzing the graph of objects, constructors and methods takes place at compile time. Pure.DI notifies the developer at compile time of missing or cyclic dependencies, cases when some dependencies are not suitable for injection, etc. +- Does not add dependencies to any additional assembly. +- Since the generated code uses primitive language constructs to create object compositions and does not use any libraries, you can easily debug the object composition code as regular code in your application. + A single instance of the _Composition_ class is defined as a static resource in [App.xaml](/samples/AvaloniaApp/App.axaml) for later use within the _xaml_ markup everywhere: -```xaml +```xml - - - - + + + + + + + + ``` +This markup fragment + +```xml + + + +``` + +creates a shared resource of type `Composition` and with key _‘Composition’_, which will be further used as a data context in the views. + The associated application [App.axaml.cs](/samples/AvaloniaApp/App.axaml.cs) class is looking like: ```c# @@ -85,20 +110,27 @@ public class App : Application } ``` -All previously defined composition roots are now accessible from [markup](/samples/AvaloniaApp/Views/MainWindow.xaml) without any effort, such as _ClockViewModel_: +Advantages over classical DI container libraries: +- No explicit initialisation of data contexts is required. Data contexts are configured directly in `.axaml` files according to the MVVM approach. +- The code is simpler, more compact, and requires less maintenance effort. +- The main window is created in a pure DI paradigm, and it can be easily supplied with all necessary dependencies via DI as regular types. + +You can now use bindings to model views without even editing the views `.cs` code files. All previously defined composition roots are now accessible from [markup](/samples/AvaloniaApp/Views/MainWindow.xaml) without any effort, such as _ClockViewModel_: -```xaml +```xml + Icon="/Assets/avalonia-logo.ico" + FontFamily="Consolas" + FontWeight="Bold"> @@ -108,6 +140,28 @@ All previously defined composition roots are now accessible from [markup](/sampl ``` +To use bindings in views: + +- You can set a shared resource as a data context + + `DataContext="{StaticResource Composition}"` + +- Specify the data type in the context: + + `xmlns:app="clr-namespace:AvaloniaApp"` + + `x:DataType="app:Composition"` + +- Use the bindings as usual: + + `Title="{Binding ClockViewModel.Time}"` + +Advantages over classical DI container libraries: +- The code-behind `.cs` files for views are free of any logic. +- This approach works just as well during design time. +- You can easily use different view models in a single view. +- Bindings depend on properties through abstractions, which additionally ensures weak coupling of types in application. This is in line with the basic principles of DI. + The [project file](/samples/AvaloniaApp/AvaloniaApp.csproj) looks like this: ```xml diff --git a/readme/AvaloniaPageTemplate.md b/readme/AvaloniaPageTemplate.md index 59f6ac4ec..7306e9dc6 100644 --- a/readme/AvaloniaPageTemplate.md +++ b/readme/AvaloniaPageTemplate.md @@ -7,9 +7,12 @@ This example demonstrates the creation of a [Avalonia](https://avaloniaui.net/) > [!NOTE] > [Another example](samples/SingleRootAvaloniaApp) with Avalonia shows how to create an application with a single composition root. -The definition of the composition is in [Composition.cs](/samples/AvaloniaApp/Composition.cs). You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: +The definition of the composition is in [Composition.cs](/samples/AvaloniaApp/Composition.cs). This class setups how the composition of objects will be created for the application. You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() @@ -32,24 +35,46 @@ internal partial class Composition } ``` +Advantages over classical DI container libraries: +- No performance impact or side effects when creating composition of objects. +- All logic for analyzing the graph of objects, constructors and methods takes place at compile time. Pure.DI notifies the developer at compile time of missing or cyclic dependencies, cases when some dependencies are not suitable for injection, etc. +- Does not add dependencies to any additional assembly. +- Since the generated code uses primitive language constructs to create object compositions and does not use any libraries, you can easily debug the object composition code as regular code in your application. + A single instance of the _Composition_ class is defined as a static resource in [App.xaml](/samples/AvaloniaApp/App.axaml) for later use within the _xaml_ markup everywhere: -```xaml +```xml - - - - + + + + + + + + ``` +This markup fragment + +```xml + + + +``` + +creates a shared resource of type `Composition` and with key _‘Composition’_, which will be further used as a data context in the views. + The associated application [App.axaml.cs](/samples/AvaloniaApp/App.axaml.cs) class is looking like: ```c# @@ -85,20 +110,27 @@ public class App : Application } ``` -All previously defined composition roots are now accessible from [markup](/samples/AvaloniaApp/Views/MainWindow.xaml) without any effort, such as _ClockViewModel_: +Advantages over classical DI container libraries: +- No explicit initialisation of data contexts is required. Data contexts are configured directly in `.axaml` files according to the MVVM approach. +- The code is simpler, more compact, and requires less maintenance effort. +- The main window is created in a pure DI paradigm, and it can be easily supplied with all necessary dependencies via DI as regular types. + +You can now use bindings to model views without even editing the views `.cs` code files. All previously defined composition roots are now accessible from [markup](/samples/AvaloniaApp/Views/MainWindow.xaml) without any effort, such as _ClockViewModel_: -```xaml +```xml + Icon="/Assets/avalonia-logo.ico" + FontFamily="Consolas" + FontWeight="Bold"> @@ -108,6 +140,28 @@ All previously defined composition roots are now accessible from [markup](/sampl ``` +To use bindings in views: + +- You can set a shared resource as a data context + + `DataContext="{StaticResource Composition}"` + +- Specify the data type in the context: + + `xmlns:app="clr-namespace:AvaloniaApp"` + + `x:DataType="app:Composition"` + +- Use the bindings as usual: + + `Title="{Binding ClockViewModel.Time}"` + +Advantages over classical DI container libraries: +- The code-behind `.cs` files for views are free of any logic. +- This approach works just as well during design time. +- You can easily use different view models in a single view. +- Bindings depend on properties through abstractions, which additionally ensures weak coupling of types in application. This is in line with the basic principles of DI. + The [project file](/samples/AvaloniaApp/AvaloniaApp.csproj) looks like this: ```xml diff --git a/readme/BlazorServerApp.md b/readme/BlazorServerApp.md index cdbab627f..c7b5acd3d 100644 --- a/readme/BlazorServerApp.md +++ b/readme/BlazorServerApp.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a [Blazor server](https://learn.micros Composition setup file is [Composition.cs](/samples/BlazorServerApp/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() @@ -71,7 +74,7 @@ The [project file](/samples/BlazorServerApp/BlazorServerApp.csproj) looks like t all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/readme/BlazorServerAppPageTemplate.md b/readme/BlazorServerAppPageTemplate.md index 17abfd08c..cecb0043c 100644 --- a/readme/BlazorServerAppPageTemplate.md +++ b/readme/BlazorServerAppPageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a [Blazor server](https://learn.micros Composition setup file is [Composition.cs](/samples/BlazorServerApp/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() diff --git a/readme/BlazorWebAssemblyApp.md b/readme/BlazorWebAssemblyApp.md index 5f63d2eb9..aa3f3e64f 100644 --- a/readme/BlazorWebAssemblyApp.md +++ b/readme/BlazorWebAssemblyApp.md @@ -9,6 +9,9 @@ This example demonstrates the creation of a [Blazor WebAssembly](https://learn.m Composition setup file is [Composition.cs](/samples/BlazorWebAssemblyApp/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() @@ -70,7 +73,7 @@ The [project file](/samples/BlazorWebAssemblyApp/BlazorWebAssemblyApp.csproj) lo all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/readme/BlazorWebAssemblyAppPageTemplate.md b/readme/BlazorWebAssemblyAppPageTemplate.md index 4cf86d477..be3da6424 100644 --- a/readme/BlazorWebAssemblyAppPageTemplate.md +++ b/readme/BlazorWebAssemblyAppPageTemplate.md @@ -9,6 +9,9 @@ This example demonstrates the creation of a [Blazor WebAssembly](https://learn.m Composition setup file is [Composition.cs](/samples/BlazorWebAssemblyApp/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() diff --git a/readme/Console.md b/readme/Console.md index 5aedff89e..cc08346c3 100644 --- a/readme/Console.md +++ b/readme/Console.md @@ -5,7 +5,11 @@ This example demonstrates the creation of a simple console application in the pure DI paradigm using the _Pure.DI_ code generator. All code is in [one file](/samples/ShroedingersCat/Program.cs) for easy perception: ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + namespace Sample; + // Let's create an abstraction public interface IBox diff --git a/readme/ConsolePageTemplate.md b/readme/ConsolePageTemplate.md index 2d97cc1f1..0631d1dc8 100644 --- a/readme/ConsolePageTemplate.md +++ b/readme/ConsolePageTemplate.md @@ -5,7 +5,11 @@ This example demonstrates the creation of a simple console application in the pure DI paradigm using the _Pure.DI_ code generator. All code is in [one file](/samples/ShroedingersCat/Program.cs) for easy perception: ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + namespace Sample; + // Let's create an abstraction public interface IBox diff --git a/readme/GrpcService.md b/readme/GrpcService.md index fbc24a0c4..8220f741d 100644 --- a/readme/GrpcService.md +++ b/readme/GrpcService.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Web API application in the pure DI p Composition setup file is [Composition.cs](/samples/GrpcService/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() @@ -56,7 +59,7 @@ The [project file](/samples/GrpcService/GrpcService.csproj) looks like this: all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/readme/GrpcServicePageTemplate.md b/readme/GrpcServicePageTemplate.md index 47eb2e587..b655fe735 100644 --- a/readme/GrpcServicePageTemplate.md +++ b/readme/GrpcServicePageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Web API application in the pure DI p Composition setup file is [Composition.cs](/samples/GrpcService/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() diff --git a/readme/Maui.md b/readme/Maui.md index d0b4a49a4..0fe88b79b 100644 --- a/readme/Maui.md +++ b/readme/Maui.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a [MAUI application](https://learn.mic The definition of the composition is in [Composition.cs](/samples/MAUIApp/Composition.cs). You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() @@ -212,7 +215,7 @@ The [project file](/samples/MAUIApp/MAUIApp.csproj) looks like this: all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/readme/MauiPageTemplate.md b/readme/MauiPageTemplate.md index 29f2cfc42..8b47ae71b 100644 --- a/readme/MauiPageTemplate.md +++ b/readme/MauiPageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a [MAUI application](https://learn.mic The definition of the composition is in [Composition.cs](/samples/MAUIApp/Composition.cs). You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() diff --git a/readme/MinimalWebAPI.md b/readme/MinimalWebAPI.md index 61d10bbe3..7f9d6f57b 100644 --- a/readme/MinimalWebAPI.md +++ b/readme/MinimalWebAPI.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Minimal Web API application in the p Composition setup file is [Composition.cs](/samples/MinimalWebAPI/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() @@ -79,7 +82,7 @@ The [project file](/samples/WebAPI/WebAPI.csproj) looks like this: all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/readme/MinimalWebAPIPageTemplate.md b/readme/MinimalWebAPIPageTemplate.md index f9114046d..db19322b4 100644 --- a/readme/MinimalWebAPIPageTemplate.md +++ b/readme/MinimalWebAPIPageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Minimal Web API application in the p Composition setup file is [Composition.cs](/samples/MinimalWebAPI/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() diff --git a/readme/WebAPI.md b/readme/WebAPI.md index 1e6dc7b94..e6661b5ba 100644 --- a/readme/WebAPI.md +++ b/readme/WebAPI.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Web API application in the pure DI p Composition setup file is [Composition.cs](/samples/WebAPI/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() @@ -54,7 +57,7 @@ The [project file](/samples/WebAPI/WebAPI.csproj) looks like this: all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/readme/WebAPIPageTemplate.md b/readme/WebAPIPageTemplate.md index 4379731f9..745c0c515 100644 --- a/readme/WebAPIPageTemplate.md +++ b/readme/WebAPIPageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Web API application in the pure DI p Composition setup file is [Composition.cs](/samples/WebAPI/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() diff --git a/readme/WebApp.md b/readme/WebApp.md index 9cd2ff7f0..1eed1dae6 100644 --- a/readme/WebApp.md +++ b/readme/WebApp.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Web application in the pure DI parad Composition setup file is [Composition.cs](/samples/WebApp/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() @@ -54,7 +57,7 @@ The [project file](/samples/WebApp/WebApp.csproj) looks like this: all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/readme/WebAppPageTemplate.md b/readme/WebAppPageTemplate.md index bd0cce255..44e9c715f 100644 --- a/readme/WebAppPageTemplate.md +++ b/readme/WebAppPageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a Web application in the pure DI parad Composition setup file is [Composition.cs](/samples/WebApp/Composition.cs): ```c# +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition: ServiceProviderFactory { void Setup() => DI.Setup() diff --git a/readme/WinFormsApp.md b/readme/WinFormsApp.md index 702a44f90..482db49c2 100644 --- a/readme/WinFormsApp.md +++ b/readme/WinFormsApp.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a WinForms application in the pure DI The composition definition is in the file [Composition.cs](/samples/WinFormsApp/Composition.cs). Remember to define all the necessary roots of the composition, for example, this could be a main form such as _FormMain_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() diff --git a/readme/WinFormsAppNetCore.md b/readme/WinFormsAppNetCore.md index 4958c2ac7..c590a5a7d 100644 --- a/readme/WinFormsAppNetCore.md +++ b/readme/WinFormsAppNetCore.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a WinForms application in the pure DI The composition definition is in the file [Composition.cs](/samples/WinFormsAppNetCore/Composition.cs). Remember to define all the necessary roots of the composition, for example, this could be a main form such as _FormMain_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() diff --git a/readme/WinFormsAppNetCorePageTemplate.md b/readme/WinFormsAppNetCorePageTemplate.md index 7a4a9d527..8981a190b 100644 --- a/readme/WinFormsAppNetCorePageTemplate.md +++ b/readme/WinFormsAppNetCorePageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a WinForms application in the pure DI The composition definition is in the file [Composition.cs](/samples/WinFormsAppNetCore/Composition.cs). Remember to define all the necessary roots of the composition, for example, this could be a main form such as _FormMain_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() diff --git a/readme/WinFormsAppPageTemplate.md b/readme/WinFormsAppPageTemplate.md index a21705c7b..e78f8efa8 100644 --- a/readme/WinFormsAppPageTemplate.md +++ b/readme/WinFormsAppPageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a WinForms application in the pure DI The composition definition is in the file [Composition.cs](/samples/WinFormsApp/Composition.cs). Remember to define all the necessary roots of the composition, for example, this could be a main form such as _FormMain_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() diff --git a/readme/Wpf.md b/readme/Wpf.md index 9474b6174..682a37b28 100644 --- a/readme/Wpf.md +++ b/readme/Wpf.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a WPF application in the pure DI parad The definition of the composition is in [Composition.cs](/samples/WpfAppNetCore/Composition.cs). You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() diff --git a/readme/WpfPageTemplate.md b/readme/WpfPageTemplate.md index 3065ef3c9..c92ce41fe 100644 --- a/readme/WpfPageTemplate.md +++ b/readme/WpfPageTemplate.md @@ -7,6 +7,9 @@ This example demonstrates the creation of a WPF application in the pure DI parad The definition of the composition is in [Composition.cs](/samples/WpfAppNetCore/Composition.cs). You must not forget to define any necessary composition roots, for example, these can be view models such as _ClockViewModel_: ```csharp +using Pure.DI; +using static Pure.DI.Lifetime; + internal partial class Composition { void Setup() => DI.Setup() diff --git a/samples/AvaloniaApp/App.axaml b/samples/AvaloniaApp/App.axaml index f0c118e0b..f9b69e942 100644 --- a/samples/AvaloniaApp/App.axaml +++ b/samples/AvaloniaApp/App.axaml @@ -3,11 +3,17 @@ x:Class="AvaloniaApp.App" xmlns:local="using:AvaloniaApp" RequestedThemeVariant="Default"> - - - - + + + + + + + + \ No newline at end of file diff --git a/samples/AvaloniaApp/Views/MainWindow.axaml b/samples/AvaloniaApp/Views/MainWindow.axaml index 70c957298..9012dd331 100644 --- a/samples/AvaloniaApp/Views/MainWindow.axaml +++ b/samples/AvaloniaApp/Views/MainWindow.axaml @@ -2,11 +2,11 @@ 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:avaloniaApp="clr-namespace:AvaloniaApp" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaApp.Views.MainWindow" - x:DataType="avaloniaApp:Composition" DataContext="{StaticResource Composition}" + xmlns:app="clr-namespace:AvaloniaApp" + x:DataType="app:Composition" Title="{Binding ClockViewModel.Time}" Icon="/Assets/avalonia-logo.ico" FontFamily="Consolas" diff --git a/samples/AvaloniaSimpleApp/App.axaml b/samples/AvaloniaSimpleApp/App.axaml new file mode 100644 index 000000000..c91e928f8 --- /dev/null +++ b/samples/AvaloniaSimpleApp/App.axaml @@ -0,0 +1,17 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/App.axaml.cs b/samples/AvaloniaSimpleApp/App.axaml.cs new file mode 100644 index 000000000..d28d15f9b --- /dev/null +++ b/samples/AvaloniaSimpleApp/App.axaml.cs @@ -0,0 +1,24 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; + +namespace AvaloniaSimpleApp; + +public class App : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop + && Resources[nameof(Composition)] is Composition composition) + { + desktop.MainWindow = composition.MainWindow; + } + + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/AvaloniaSimpleApp.csproj b/samples/AvaloniaSimpleApp/AvaloniaSimpleApp.csproj new file mode 100644 index 000000000..eaa7ec6e1 --- /dev/null +++ b/samples/AvaloniaSimpleApp/AvaloniaSimpleApp.csproj @@ -0,0 +1,21 @@ + + + WinExe + net8.0 + enable + true + app.manifest + true + + + + + + + + + + + + + diff --git a/samples/AvaloniaSimpleApp/BusinessService.cs b/samples/AvaloniaSimpleApp/BusinessService.cs new file mode 100644 index 000000000..4dd3db29f --- /dev/null +++ b/samples/AvaloniaSimpleApp/BusinessService.cs @@ -0,0 +1,11 @@ +namespace AvaloniaSimpleApp; + +public class BusinessService(IRepository repository) + : IBusinessService +{ + public string CreateGreetings() + { + repository.RegisterSomething(); + return "Example of Dependency Injection implementation using Pure.DI"; + } +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/Composition.cs b/samples/AvaloniaSimpleApp/Composition.cs new file mode 100644 index 000000000..5717f8dac --- /dev/null +++ b/samples/AvaloniaSimpleApp/Composition.cs @@ -0,0 +1,15 @@ +namespace AvaloniaSimpleApp; + +using Pure.DI; +using static Pure.DI.Lifetime; + +public partial class Composition +{ + private static void Setup() => DI.Setup() + .Root(nameof(MainWindow)) + .Root(nameof(MainViewModel)) + + .Bind().As(Singleton).To() + .Bind().To() + .Bind().As(Singleton).To(); +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/IBusinessService.cs b/samples/AvaloniaSimpleApp/IBusinessService.cs new file mode 100644 index 000000000..c614fc6a5 --- /dev/null +++ b/samples/AvaloniaSimpleApp/IBusinessService.cs @@ -0,0 +1,6 @@ +namespace AvaloniaSimpleApp; + +public interface IBusinessService +{ + string CreateGreetings(); +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/IMainViewModel.cs b/samples/AvaloniaSimpleApp/IMainViewModel.cs new file mode 100644 index 000000000..5f7c8d431 --- /dev/null +++ b/samples/AvaloniaSimpleApp/IMainViewModel.cs @@ -0,0 +1,8 @@ +namespace AvaloniaSimpleApp; + +public interface IMainViewModel +{ + string Title { get; } + + string Greetings { get; } +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/IRepository.cs b/samples/AvaloniaSimpleApp/IRepository.cs new file mode 100644 index 000000000..b713f6087 --- /dev/null +++ b/samples/AvaloniaSimpleApp/IRepository.cs @@ -0,0 +1,6 @@ +namespace AvaloniaSimpleApp; + +public interface IRepository +{ + void RegisterSomething(); +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/MainViewModel.cs b/samples/AvaloniaSimpleApp/MainViewModel.cs new file mode 100644 index 000000000..309e397af --- /dev/null +++ b/samples/AvaloniaSimpleApp/MainViewModel.cs @@ -0,0 +1,9 @@ +namespace AvaloniaSimpleApp; + +public class MainViewModel(IBusinessService businessService) + : IMainViewModel +{ + public string Title => "Avalonia application"; + + public string Greetings => businessService.CreateGreetings(); +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/MainWindow.axaml b/samples/AvaloniaSimpleApp/MainWindow.axaml new file mode 100644 index 000000000..4b7423dba --- /dev/null +++ b/samples/AvaloniaSimpleApp/MainWindow.axaml @@ -0,0 +1,11 @@ + diff --git a/samples/AvaloniaSimpleApp/MainWindow.axaml.cs b/samples/AvaloniaSimpleApp/MainWindow.axaml.cs new file mode 100644 index 000000000..600d949f9 --- /dev/null +++ b/samples/AvaloniaSimpleApp/MainWindow.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; + +namespace AvaloniaSimpleApp; + +public partial class MainWindow : Window +{ + public MainWindow() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/Program.cs b/samples/AvaloniaSimpleApp/Program.cs new file mode 100644 index 000000000..cd2df4a86 --- /dev/null +++ b/samples/AvaloniaSimpleApp/Program.cs @@ -0,0 +1,21 @@ +using Avalonia; +using System; + +namespace AvaloniaSimpleApp; + +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. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/Repository.cs b/samples/AvaloniaSimpleApp/Repository.cs new file mode 100644 index 000000000..49df169d7 --- /dev/null +++ b/samples/AvaloniaSimpleApp/Repository.cs @@ -0,0 +1,8 @@ +namespace AvaloniaSimpleApp; + +public class Repository: IRepository +{ + public void RegisterSomething() + { + } +} \ No newline at end of file diff --git a/samples/AvaloniaSimpleApp/app.manifest b/samples/AvaloniaSimpleApp/app.manifest new file mode 100644 index 000000000..4be7ac419 --- /dev/null +++ b/samples/AvaloniaSimpleApp/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/samples/SingleRootAvaloniaApp/App.axaml b/samples/SingleRootAvaloniaApp/App.axaml index f0c118e0b..a8977a559 100644 --- a/samples/SingleRootAvaloniaApp/App.axaml +++ b/samples/SingleRootAvaloniaApp/App.axaml @@ -3,11 +3,16 @@ x:Class="AvaloniaApp.App" xmlns:local="using:AvaloniaApp" RequestedThemeVariant="Default"> - - - + + + + + + + \ No newline at end of file diff --git a/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml b/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml index 7599bed97..b264313ab 100644 --- a/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml +++ b/samples/SingleRootAvaloniaApp/Views/MainWindow.axaml @@ -2,11 +2,11 @@ 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:avaloniaApp="clr-namespace:AvaloniaApp" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" x:Class="AvaloniaApp.Views.MainWindow" - x:DataType="avaloniaApp:Composition" DataContext="{StaticResource Composition}" + xmlns:app="clr-namespace:AvaloniaApp" + x:DataType="app:Composition" Title="{Binding Root.ClockViewModel.Time}" Icon="/Assets/avalonia-logo.ico" FontFamily="Consolas"