Wrote a small helper class with extension methods to register the Nuclex.Avalonia MVVM services to a Microsoft.Extensions.DependencyInjection IoC container
This commit is contained in:
		
						commit
						708f87357e
					
				
					 4 changed files with 278 additions and 0 deletions
				
			
		
							
								
								
									
										116
									
								
								Source/DependencyInjectedWindowManager.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										116
									
								
								Source/DependencyInjectedWindowManager.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,116 @@
 | 
			
		|||
#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.Avalonia.AutoBinding;
 | 
			
		||||
 | 
			
		||||
namespace Nuclex.Avalonia.DependencyInjection {
 | 
			
		||||
 | 
			
		||||
  /// <summary>
 | 
			
		||||
  ///   Window manager that is using Microsoft's dependency injection interfaces
 | 
			
		||||
  /// </summary>
 | 
			
		||||
#if NET6_0_OR_GREATER
 | 
			
		||||
  [SupportedOSPlatform("windows")]
 | 
			
		||||
#endif
 | 
			
		||||
  public class DependencyInjectedWindowManager : WindowManager {
 | 
			
		||||
 | 
			
		||||
    #region class WindowScope
 | 
			
		||||
 | 
			
		||||
    /// <summary>Manages a window-specific service scope</summary>
 | 
			
		||||
    private class WindowScope : IWindowScope, IDisposable {
 | 
			
		||||
 | 
			
		||||
      /// <summary>Initializes a new service scope for the window</summary>
 | 
			
		||||
      /// <param name="serviceProvider">
 | 
			
		||||
      ///   Service provider in which to create a scope
 | 
			
		||||
      /// </param>
 | 
			
		||||
      public WindowScope(IServiceProvider serviceProvider) {
 | 
			
		||||
        this.serviceScope = serviceProvider.CreateScope();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /// <summary>Creates an instance of the specified type in the scope</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>
 | 
			
		||||
      public object CreateInstance(Type type) {
 | 
			
		||||
        return this.serviceScope.ServiceProvider.GetRequiredService(type);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /// <summary>Immediately destroys all services owned by the scope</summary>
 | 
			
		||||
      public void Dispose() {
 | 
			
		||||
        if(this.serviceScope != null) {
 | 
			
		||||
          this.serviceScope.Dispose();
 | 
			
		||||
          this.serviceScope = null;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      /// <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 a new scope in which window-specific services will live</summary>
 | 
			
		||||
    /// <returns>The new scope managing the lifetime of window-specific services</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.Avalonia.DependencyInjection
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue