Implemented service scope support
This commit is contained in:
parent
03954e772a
commit
573b7ab93d
28
Documents/images/platforms-windows-badge.svg
Normal file
28
Documents/images/platforms-windows-badge.svg
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="140" height="20" role="img" aria-label="platforms: linux windows">
|
||||||
|
<title>platforms: linux and windows</title>
|
||||||
|
<linearGradient id="s" x2="0" y2="100%">
|
||||||
|
<stop offset="0" stop-color="#bbb" stop-opacity=".1" />
|
||||||
|
<stop offset="1" stop-opacity=".1" />
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="r">
|
||||||
|
<rect width="140" height="20" rx="3" fill="#fff" />
|
||||||
|
</clipPath>
|
||||||
|
<g clip-path="url(#r)">
|
||||||
|
<rect width="63" height="20" fill="#555" />
|
||||||
|
<rect x="63" width="77" height="20" fill="#00a4ef" />
|
||||||
|
<rect width="140" height="20" fill="url(#s)" />
|
||||||
|
</g>
|
||||||
|
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
|
||||||
|
<text aria-hidden="true" x="325" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="530">platforms</text>
|
||||||
|
<text x="325" y="140" transform="scale(.1)" fill="#fff" textLength="530">platforms</text>
|
||||||
|
<text aria-hidden="true" x="1100" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="470">windows</text>
|
||||||
|
<text x="1100" y="140" transform="scale(.1)" fill="#fff" textLength="470">windows</text>
|
||||||
|
</g>
|
||||||
|
<g id="windows-logo" style="fill:#fff" transform="matrix(0.05,0,0,0.05,67,2)">
|
||||||
|
<path id="upper-left" d="m 2.609,144.999 h 119.892 c 1.381,0 2.5,-1.119 2.5,-2.5 V 28.681 c 0,-0.722 -0.312,-1.408 -0.855,-1.883 -0.543,-0.475 -1.261,-0.693 -1.981,-0.594 L 2.164,42.5 C 0.923,42.669 -0.001,43.728 0,44.98 l 0.109,97.521 c 0.002,1.38 1.121,2.498 2.5,2.498 z" />
|
||||||
|
<path id="upper-right" d="m 139.999,25.775 v 116.724 c 0,1.381 1.119,2.5 2.5,2.5 H 302.46 c 1.381,0 2.5,-1.119 2.5,-2.5 V 2.5 c 0,-0.726 -0.315,-1.416 -0.864,-1.891 -0.548,-0.475 -1.275,-0.687 -1.996,-0.583 L 142.139,23.301 c -1.229,0.179 -2.14,1.233 -2.14,2.474 z" />
|
||||||
|
<path id="lower-left" d="m 122.501,279.948 c 0.601,0 1.186,-0.216 1.644,-0.616 0.544,-0.475 0.856,-1.162 0.856,-1.884 V 162.5 c 0,-1.381 -1.119,-2.5 -2.5,-2.5 H 2.592 c -0.663,0 -1.299,0.263 -1.768,0.732 -0.469,0.469 -0.732,1.105 -0.732,1.768 l 0.006,98.515 c 0,1.25 0.923,2.307 2.16,2.477 l 119.903,16.434 c 0.113,0.014 0.227,0.022 0.34,0.022 z" />
|
||||||
|
<path id="lower-right" d="m 302.46,305 c 0.599,0 1.182,-0.215 1.64,-0.613 0.546,-0.475 0.86,-1.163 0.86,-1.887 l 0.04,-140 c 0,-0.663 -0.263,-1.299 -0.732,-1.768 C 303.799,160.263 303.163,160 302.5,160 H 142.499 c -1.381,0 -2.5,1.119 -2.5,2.5 v 117.496 c 0,1.246 0.918,2.302 2.151,2.476 l 159.961,22.504 c 0.117,0.016 0.233,0.024 0.349,0.024 z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
27
Documents/images/status-mature-and-stable-badge.svg
Normal file
27
Documents/images/status-mature-and-stable-badge.svg
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="189" height="20" role="img" aria-label="status: mature and stable">
|
||||||
|
<title>status: early planning phase</title>
|
||||||
|
<linearGradient id="s" x2="0" y2="100%">
|
||||||
|
<stop offset="0" stop-color="#bbb" stop-opacity=".1" />
|
||||||
|
<stop offset="1" stop-opacity=".1" />
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="r">
|
||||||
|
<rect width="189" height="20" rx="3" fill="#fff" />
|
||||||
|
</clipPath>
|
||||||
|
<g clip-path="url(#r)">
|
||||||
|
<rect width="43" height="20" fill="#555" />
|
||||||
|
<rect x="43" width="149" height="20" fill="darkgreen" />
|
||||||
|
<rect width="189" height="20" fill="url(#s)" />
|
||||||
|
</g>
|
||||||
|
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110">
|
||||||
|
<text aria-hidden="true" x="225" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="330">status</text>
|
||||||
|
<text x="225" y="140" transform="scale(.1)" fill="#fff" textLength="330">status</text>
|
||||||
|
<text aria-hidden="true" x="1245" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1150">mature and stable</text>
|
||||||
|
<text x="1245" y="140" transform="scale(.1)" fill="#fff" textLength="1150">mature and stable</text>
|
||||||
|
</g>
|
||||||
|
<g id="package" style="stroke:#fff;fill:none" transform="matrix(0.75,0,0,0.75,47,1)">
|
||||||
|
<path id="box" d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/>
|
||||||
|
<polyline points="3.27 6.96 12 12.01 20.73 6.96"/>
|
||||||
|
<line x1="12" y1="22.08" x2="12" y2="12"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,10 +1,4 @@
|
|||||||
- **Status:** Stable and mature. Several projects are using this library,
|
Nuclex.Windows.Forms.DependencyInjection  
|
||||||
and it has received extensive testing on Linux and Windows.
|
|
||||||
|
|
||||||
- **Platforms:** Cross-platform, developed on Linux but also tested and
|
|
||||||
working without any known issues on Windows.
|
|
||||||
|
|
||||||
Nuclex.Windows.Forms.DependencyInjection
|
|
||||||
========================================
|
========================================
|
||||||
|
|
||||||
Nuclex.Windows.Forms is a standalone, lightweight MVVM library that lets you "display"
|
Nuclex.Windows.Forms is a standalone, lightweight MVVM library that lets you "display"
|
||||||
|
@ -1,71 +1,118 @@
|
|||||||
#region Apache License 2.0
|
#region Apache License 2.0
|
||||||
/*
|
/*
|
||||||
Nuclex .NET Framework
|
Nuclex .NET Framework
|
||||||
Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
|
Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
#endregion // Apache License 2.0
|
#endregion // Apache License 2.0
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
using Nuclex.Windows.Forms.AutoBinding;
|
using Nuclex.Windows.Forms.AutoBinding;
|
||||||
|
|
||||||
namespace Nuclex.Windows.Forms.DependencyInjection {
|
namespace Nuclex.Windows.Forms.DependencyInjection {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Window manager that is using Microsoft's dependency injection interfaces
|
/// Window manager that is using Microsoft's dependency injection interfaces
|
||||||
/// </summary>
|
/// </summary>
|
||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
#endif
|
#endif
|
||||||
public class DependencyInjectedWindowManager : WindowManager {
|
public class DependencyInjectedWindowManager : WindowManager {
|
||||||
|
|
||||||
/// <summary>Initializes a new window manager</summary>
|
#region class WindowScope
|
||||||
/// <param name="serviceProvider">
|
|
||||||
/// Dependency injector the window manager uses to construct view models
|
/// <summary>Manages a window-specific service scope</summary>
|
||||||
/// </param>
|
private class WindowScope : IWindowScope, IDisposable {
|
||||||
/// <param name="autoBinder">
|
|
||||||
/// View model binder that will be used to bind all created views to their models
|
/// <summary>Initializes a new service scope for the window</summary>
|
||||||
/// </param>
|
/// <param name="serviceProvider">
|
||||||
public DependencyInjectedWindowManager(
|
/// Service provider in which to create a scope
|
||||||
IServiceProvider serviceProvider, IAutoBinder autoBinder = null
|
/// </param>
|
||||||
) :
|
public WindowScope(IServiceProvider serviceProvider) {
|
||||||
base(autoBinder) {
|
this.serviceScope = serviceProvider.CreateScope();
|
||||||
this.serviceProvider = serviceProvider;
|
}
|
||||||
}
|
|
||||||
|
/// <summary>Creates an instance of the specified type in the scope</summary>
|
||||||
/// <summary>Creates an instance of the specified type</summary>
|
/// <param name="type">Type an instance will be created of</param>
|
||||||
/// <param name="type">Type an instance will be created of</param>
|
/// <returns>The created instance</returns>
|
||||||
/// <returns>The created instance</returns>
|
/// <remarks>
|
||||||
/// <remarks>
|
/// Use this to wire up your dependency injection container. By default,
|
||||||
/// Use this to wire up your dependency injection container. By default,
|
/// the Activator class will be used to create instances which only works
|
||||||
/// the Activator class will be used to create instances which only works
|
/// if all of your view models are concrete classes.
|
||||||
/// if all of your view models are concrete classes.
|
/// </remarks>
|
||||||
/// </remarks>
|
public object CreateInstance(Type type) {
|
||||||
protected override object CreateInstance(Type type) {
|
return this.serviceScope.ServiceProvider.GetRequiredService(type);
|
||||||
return this.serviceProvider.GetRequiredService(type);
|
}
|
||||||
}
|
|
||||||
|
/// <summary>Immediately destroys all services owned by the scope</summary>
|
||||||
/// <summary>The service provider used to create new instances</summary>
|
public void Dispose() {
|
||||||
private readonly IServiceProvider serviceProvider;
|
if(this.serviceScope != null) {
|
||||||
|
this.serviceScope.Dispose();
|
||||||
}
|
this.serviceScope = null;
|
||||||
|
}
|
||||||
} // namespace Nuclex.Windows.Forms.DependencyInjection
|
}
|
||||||
|
|
||||||
|
/// <summary>Service scope that will be used to create instances</summary>
|
||||||
|
private IServiceScope serviceScope;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion // class WindowScope
|
||||||
|
|
||||||
|
/// <summary>Initializes a new window manager</summary>
|
||||||
|
/// <param name="serviceProvider">
|
||||||
|
/// Dependency injector the window manager uses to construct view models
|
||||||
|
/// </param>
|
||||||
|
/// <param name="autoBinder">
|
||||||
|
/// View model binder that will be used to bind all created views to their models
|
||||||
|
/// </param>
|
||||||
|
public DependencyInjectedWindowManager(
|
||||||
|
IServiceProvider serviceProvider, IAutoBinder autoBinder = null
|
||||||
|
) :
|
||||||
|
base(autoBinder) {
|
||||||
|
this.serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Creates an instance of the specified type</summary>
|
||||||
|
/// <param name="type">Type an instance will be created of</param>
|
||||||
|
/// <returns>The created instance</returns>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this to wire up your dependency injection container. By default,
|
||||||
|
/// the Activator class will be used to create instances which only works
|
||||||
|
/// if all of your view models are concrete classes.
|
||||||
|
/// </remarks>
|
||||||
|
protected override object CreateInstance(Type type) {
|
||||||
|
return this.serviceProvider.GetRequiredService(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Creates an instance of the specified type in a new scope</summary>
|
||||||
|
/// <param name="type">Type an instance will be created of</param>
|
||||||
|
/// <returns>The created instance and the scope in which it lives</returns>
|
||||||
|
protected override IWindowScope CreateWindowScope() {
|
||||||
|
return new WindowScope(this.serviceProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>The service provider used to create new instances</summary>
|
||||||
|
private readonly IServiceProvider serviceProvider;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Nuclex.Windows.Forms.DependencyInjection
|
||||||
|
@ -22,8 +22,8 @@ using System;
|
|||||||
#if NET6_0_OR_GREATER
|
#if NET6_0_OR_GREATER
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
using Nuclex.Windows.Forms.AutoBinding;
|
using Nuclex.Windows.Forms.AutoBinding;
|
||||||
using Nuclex.Windows.Forms.CommonDialogs;
|
using Nuclex.Windows.Forms.CommonDialogs;
|
||||||
@ -37,52 +37,52 @@ namespace Nuclex.Windows.Forms.DependencyInjection {
|
|||||||
#endif
|
#endif
|
||||||
public static class MvvmExtensions {
|
public static class MvvmExtensions {
|
||||||
|
|
||||||
/// <summary>Registers all MVVM supporting services for a WinForms application</summary>
|
/// <summary>Registers all MVVM supporting services for a WinForms application</summary>
|
||||||
/// <param name="services">Service collection the services will be registered to</param>
|
/// <param name="services">Service collection the services will be registered to</param>
|
||||||
/// <returns>The service collection for method chaining</returns>
|
/// <returns>The service collection for method chaining</returns>
|
||||||
public static IServiceCollection AddMvvm(this IServiceCollection services) {
|
public static IServiceCollection AddMvvm(this IServiceCollection services) {
|
||||||
|
|
||||||
// The window manager keeps track of which Window is in the foreground
|
// The window manager keeps track of which Window is in the foreground
|
||||||
// and handles opening modal or modeless windows for which it either
|
// and handles opening modal or modeless windows for which it either
|
||||||
// binds provided view models or requests new instances.
|
// binds provided view models or requests new instances.
|
||||||
services.AddSingleton<WindowManager, DependencyInjectedWindowManager>();
|
services.AddSingleton<WindowManager, DependencyInjectedWindowManager>();
|
||||||
|
|
||||||
// The IWindowManager is the main interface that should be used to
|
// The IWindowManager is the main interface that should be used to
|
||||||
// create new windows and dialogs
|
// create new windows and dialogs
|
||||||
services.AddSingleton<IWindowManager>(
|
services.AddSingleton<IWindowManager>(
|
||||||
sp => sp.GetRequiredService<WindowManager>()
|
sp => sp.GetRequiredService<WindowManager>()
|
||||||
);
|
);
|
||||||
|
|
||||||
// The IActiveWindowTracker is a very simple interface to let Windows Forms
|
// The IActiveWindowTracker is a very simple interface to let Windows Forms
|
||||||
// extensions that need to display message boxes or other things query for
|
// extensions that need to display message boxes or other things query for
|
||||||
// the currently active top-level window.
|
// the currently active top-level window.
|
||||||
services.AddSingleton<IActiveWindowTracker>(
|
services.AddSingleton<IActiveWindowTracker>(
|
||||||
sp => sp.GetRequiredService<WindowManager>()
|
sp => sp.GetRequiredService<WindowManager>()
|
||||||
);
|
);
|
||||||
|
|
||||||
// The auto binder uses convention-over-configuration to automatically
|
// The auto binder uses convention-over-configuration to automatically
|
||||||
// establish data bindings or call view model methods that share their name
|
// establish data bindings or call view model methods that share their name
|
||||||
// with button controls.
|
// with button controls.
|
||||||
services.AddSingleton<IAutoBinder, ConventionBinder>();
|
services.AddSingleton<IAutoBinder, ConventionBinder>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Registers all MVVM supporting services for a WinForms application</summary>
|
/// <summary>Registers all MVVM supporting services for a WinForms application</summary>
|
||||||
/// <param name="services">Service collection the services will be registered to</param>
|
/// <param name="services">Service collection the services will be registered to</param>
|
||||||
/// <returns>The service collection for method chaining</returns>
|
/// <returns>The service collection for method chaining</returns>
|
||||||
public static IServiceCollection AddCommonDialogs(this IServiceCollection services) {
|
public static IServiceCollection AddCommonDialogs(this IServiceCollection services) {
|
||||||
|
|
||||||
// Implementation of the message service that uses plain MessageBoxes
|
// Implementation of the message service that uses plain MessageBoxes
|
||||||
// from the Win32 API to display messages to the user
|
// from the Win32 API to display messages to the user
|
||||||
services.AddSingleton<IMessageService, StandardMessageBoxManager>();
|
services.AddSingleton<IMessageService, StandardMessageBoxManager>();
|
||||||
|
|
||||||
// Common dialog adapter that uses the built-in common dialogs from
|
// Common dialog adapter that uses the built-in common dialogs from
|
||||||
// basic WinForms to display file open, save or print dialogs
|
// basic WinForms to display file open, save or print dialogs
|
||||||
services.AddSingleton<ICommonDialogService, CommonDialogManager>();
|
services.AddSingleton<ICommonDialogService, CommonDialogManager>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user