diff --git a/Documents/images/platforms-windows-badge.svg b/Documents/images/platforms-windows-badge.svg
new file mode 100644
index 0000000..685cc0d
--- /dev/null
+++ b/Documents/images/platforms-windows-badge.svg
@@ -0,0 +1,28 @@
+
+
diff --git a/Documents/images/status-mature-and-stable-badge.svg b/Documents/images/status-mature-and-stable-badge.svg
new file mode 100644
index 0000000..400fce7
--- /dev/null
+++ b/Documents/images/status-mature-and-stable-badge.svg
@@ -0,0 +1,27 @@
+
+
diff --git a/ReadMe.md b/ReadMe.md
index 7a63491..67b5989 100644
--- a/ReadMe.md
+++ b/ReadMe.md
@@ -1,10 +1,4 @@
- - **Status:** Stable and mature. Several projects are using this library,
- 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.DependencyInjection  
========================================
Nuclex.Windows.Forms is a standalone, lightweight MVVM library that lets you "display"
diff --git a/Source/DependencyInjectedWindowManager.cs b/Source/DependencyInjectedWindowManager.cs
index 86d1a09..6cb9e59 100644
--- a/Source/DependencyInjectedWindowManager.cs
+++ b/Source/DependencyInjectedWindowManager.cs
@@ -1,71 +1,118 @@
-#region Apache License 2.0
-/*
-Nuclex .NET Framework
-Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-#endregion // Apache License 2.0
-
-using System;
-
-#if NET6_0_OR_GREATER
-using System.Runtime.Versioning;
-#endif
-
-using Microsoft.Extensions.DependencyInjection;
-
-using Nuclex.Windows.Forms.AutoBinding;
-
-namespace Nuclex.Windows.Forms.DependencyInjection {
-
- ///
- /// Window manager that is using Microsoft's dependency injection interfaces
- ///
-#if NET6_0_OR_GREATER
- [SupportedOSPlatform("windows")]
-#endif
- public class DependencyInjectedWindowManager : WindowManager {
-
- /// Initializes a new window manager
- ///
- /// Dependency injector the window manager uses to construct view models
- ///
- ///
- /// View model binder that will be used to bind all created views to their models
- ///
- public DependencyInjectedWindowManager(
- IServiceProvider serviceProvider, IAutoBinder autoBinder = null
- ) :
- base(autoBinder) {
- this.serviceProvider = serviceProvider;
- }
-
- /// Creates an instance of the specified type
- /// Type an instance will be created of
- /// The created instance
- ///
- /// 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.
- ///
- protected override object CreateInstance(Type type) {
- return this.serviceProvider.GetRequiredService(type);
- }
-
- /// The service provider used to create new instances
- private readonly IServiceProvider serviceProvider;
-
- }
-
-} // namespace Nuclex.Windows.Forms.DependencyInjection
+#region Apache License 2.0
+/*
+Nuclex .NET Framework
+Copyright (C) 2002-2024 Markus Ewald / Nuclex Development Labs
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+#endregion // Apache License 2.0
+
+using System;
+
+#if NET6_0_OR_GREATER
+using System.Runtime.Versioning;
+#endif
+
+using Microsoft.Extensions.DependencyInjection;
+
+using Nuclex.Windows.Forms.AutoBinding;
+
+namespace Nuclex.Windows.Forms.DependencyInjection {
+
+ ///
+ /// Window manager that is using Microsoft's dependency injection interfaces
+ ///
+#if NET6_0_OR_GREATER
+ [SupportedOSPlatform("windows")]
+#endif
+ public class DependencyInjectedWindowManager : WindowManager {
+
+ #region class WindowScope
+
+ /// Manages a window-specific service scope
+ private class WindowScope : IWindowScope, IDisposable {
+
+ /// Initializes a new service scope for the window
+ ///
+ /// Service provider in which to create a scope
+ ///
+ public WindowScope(IServiceProvider serviceProvider) {
+ this.serviceScope = serviceProvider.CreateScope();
+ }
+
+ /// Creates an instance of the specified type in the scope
+ /// Type an instance will be created of
+ /// The created instance
+ ///
+ /// 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.
+ ///
+ public object CreateInstance(Type type) {
+ return this.serviceScope.ServiceProvider.GetRequiredService(type);
+ }
+
+ /// Immediately destroys all services owned by the scope
+ public void Dispose() {
+ if(this.serviceScope != null) {
+ this.serviceScope.Dispose();
+ this.serviceScope = null;
+ }
+ }
+
+ /// Service scope that will be used to create instances
+ private IServiceScope serviceScope;
+
+ }
+
+ #endregion // class WindowScope
+
+ /// Initializes a new window manager
+ ///
+ /// Dependency injector the window manager uses to construct view models
+ ///
+ ///
+ /// View model binder that will be used to bind all created views to their models
+ ///
+ public DependencyInjectedWindowManager(
+ IServiceProvider serviceProvider, IAutoBinder autoBinder = null
+ ) :
+ base(autoBinder) {
+ this.serviceProvider = serviceProvider;
+ }
+
+ /// Creates an instance of the specified type
+ /// Type an instance will be created of
+ /// The created instance
+ ///
+ /// 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.
+ ///
+ protected override object CreateInstance(Type type) {
+ return this.serviceProvider.GetRequiredService(type);
+ }
+
+ /// Creates an instance of the specified type in a new scope
+ /// Type an instance will be created of
+ /// The created instance and the scope in which it lives
+ protected override IWindowScope CreateWindowScope() {
+ return new WindowScope(this.serviceProvider);
+ }
+
+ /// The service provider used to create new instances
+ private readonly IServiceProvider serviceProvider;
+
+ }
+
+} // namespace Nuclex.Windows.Forms.DependencyInjection
diff --git a/Source/MvvmExtensions.cs b/Source/MvvmExtensions.cs
index 8de87c8..514248f 100644
--- a/Source/MvvmExtensions.cs
+++ b/Source/MvvmExtensions.cs
@@ -22,8 +22,8 @@ using System;
#if NET6_0_OR_GREATER
using System.Runtime.Versioning;
#endif
-
-using Microsoft.Extensions.DependencyInjection;
+
+using Microsoft.Extensions.DependencyInjection;
using Nuclex.Windows.Forms.AutoBinding;
using Nuclex.Windows.Forms.CommonDialogs;
@@ -37,52 +37,52 @@ namespace Nuclex.Windows.Forms.DependencyInjection {
#endif
public static class MvvmExtensions {
- /// Registers all MVVM supporting services for a WinForms application
- /// Service collection the services will be registered to
- /// The service collection for method chaining
+ /// Registers all MVVM supporting services for a WinForms application
+ /// Service collection the services will be registered to
+ /// The service collection for method chaining
public static IServiceCollection AddMvvm(this IServiceCollection services) {
-
- // The window manager keeps track of which Window is in the foreground
- // and handles opening modal or modeless windows for which it either
- // binds provided view models or requests new instances.
- services.AddSingleton();
-
- // The IWindowManager is the main interface that should be used to
- // create new windows and dialogs
- services.AddSingleton(
- sp => sp.GetRequiredService()
- );
-
- // The IActiveWindowTracker is a very simple interface to let Windows Forms
- // extensions that need to display message boxes or other things query for
- // the currently active top-level window.
- services.AddSingleton(
- sp => sp.GetRequiredService()
- );
-
- // The auto binder uses convention-over-configuration to automatically
- // establish data bindings or call view model methods that share their name
- // with button controls.
- services.AddSingleton();
-
- return services;
-
+
+ // The window manager keeps track of which Window is in the foreground
+ // and handles opening modal or modeless windows for which it either
+ // binds provided view models or requests new instances.
+ services.AddSingleton();
+
+ // The IWindowManager is the main interface that should be used to
+ // create new windows and dialogs
+ services.AddSingleton(
+ sp => sp.GetRequiredService()
+ );
+
+ // The IActiveWindowTracker is a very simple interface to let Windows Forms
+ // extensions that need to display message boxes or other things query for
+ // the currently active top-level window.
+ services.AddSingleton(
+ sp => sp.GetRequiredService()
+ );
+
+ // The auto binder uses convention-over-configuration to automatically
+ // establish data bindings or call view model methods that share their name
+ // with button controls.
+ services.AddSingleton();
+
+ return services;
+
}
- /// Registers all MVVM supporting services for a WinForms application
- /// Service collection the services will be registered to
- /// The service collection for method chaining
+ /// Registers all MVVM supporting services for a WinForms application
+ /// Service collection the services will be registered to
+ /// The service collection for method chaining
public static IServiceCollection AddCommonDialogs(this IServiceCollection services) {
// Implementation of the message service that uses plain MessageBoxes
// from the Win32 API to display messages to the user
- services.AddSingleton();
-
- // Common dialog adapter that uses the built-in common dialogs from
+ services.AddSingleton();
+
+ // Common dialog adapter that uses the built-in common dialogs from
// basic WinForms to display file open, save or print dialogs
- services.AddSingleton();
-
- return services;
+ services.AddSingleton();
+
+ return services;
}