diff --git a/src/ReactiveMarbles.Navigation.sln b/src/ReactiveMarbles.Navigation.sln
index 4df079e..8b62846 100644
--- a/src/ReactiveMarbles.Navigation.sln
+++ b/src/ReactiveMarbles.Navigation.sln
@@ -33,6 +33,14 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ReactiveMarbles.ViewModel.M
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ViewModel.MAUI.Example", "ViewModel.MAUI.Example\ViewModel.MAUI.Example.csproj", "{DE39BF42-E055-4797-9807-6AAA44089FE5}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ViewModelNav", "ViewModelNav", "{8EE96502-4F77-460E-89F5-5CD222CE0896}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ViewNav", "ViewNav", "{C11FB3F2-E114-448F-84AD-491EF1E0E7E8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveMarbles.View.Core", "ReactiveMarbles.View.Core\ReactiveMarbles.View.Core.csproj", "{F715B429-EF30-4716-ADDB-24BC99892336}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ReactiveMarbles.View.Wpf", "ReactiveMarbles.View.Wpf\ReactiveMarbles.View.Wpf.csproj", "{E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -85,14 +93,32 @@ Global
{DE39BF42-E055-4797-9807-6AAA44089FE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE39BF42-E055-4797-9807-6AAA44089FE5}.Release|Any CPU.Build.0 = Release|Any CPU
{DE39BF42-E055-4797-9807-6AAA44089FE5}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {F715B429-EF30-4716-ADDB-24BC99892336}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F715B429-EF30-4716-ADDB-24BC99892336}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F715B429-EF30-4716-ADDB-24BC99892336}.Design|Any CPU.ActiveCfg = Design|Any CPU
+ {F715B429-EF30-4716-ADDB-24BC99892336}.Design|Any CPU.Build.0 = Design|Any CPU
+ {F715B429-EF30-4716-ADDB-24BC99892336}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F715B429-EF30-4716-ADDB-24BC99892336}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD}.Design|Any CPU.ActiveCfg = Design|Any CPU
+ {E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD}.Design|Any CPU.Build.0 = Design|Any CPU
+ {E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
+ {6B5A20B7-CAA7-4CBF-B48F-6EFFE9414610} = {8EE96502-4F77-460E-89F5-5CD222CE0896}
+ {990C0E6D-0C09-482D-8AFA-F135EC206C43} = {8EE96502-4F77-460E-89F5-5CD222CE0896}
+ {CD830D09-4558-403B-9504-C0CFD90FDC3B} = {8EE96502-4F77-460E-89F5-5CD222CE0896}
{5E67BC1D-9AD7-4DDA-B095-6EFE99AD2C2E} = {6E654C37-7F3A-4E17-83C1-CA8BC9B54476}
{67688407-5509-4158-B9C3-5C2076E4946C} = {6E654C37-7F3A-4E17-83C1-CA8BC9B54476}
+ {267783AB-7239-42A1-9596-22F53B8884D1} = {8EE96502-4F77-460E-89F5-5CD222CE0896}
{DE39BF42-E055-4797-9807-6AAA44089FE5} = {6E654C37-7F3A-4E17-83C1-CA8BC9B54476}
+ {F715B429-EF30-4716-ADDB-24BC99892336} = {C11FB3F2-E114-448F-84AD-491EF1E0E7E8}
+ {E4F89A0E-71D0-48D9-9865-1BCB98ADB1FD} = {C11FB3F2-E114-448F-84AD-491EF1E0E7E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {489B52FF-BC1B-435B-8412-301C8A46D473}
diff --git a/src/ReactiveMarbles.View.Core/INotifiyRoutableView.cs b/src/ReactiveMarbles.View.Core/INotifiyRoutableView.cs
new file mode 100644
index 0000000..b8dbb1a
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/INotifiyRoutableView.cs
@@ -0,0 +1,48 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System.Reactive.Disposables;
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// INotifiy Routable ViewModel.
+///
+///
+public interface INotifiyRoutableView : Mvvm.IRxObject, IUseHostedNavigation
+{
+ ///
+ /// Gets the name.
+ ///
+ ///
+ /// The name.
+ ///
+ string? Name { get; }
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ void WhenNavigatedFrom(IViewNavigationEventArgs e);
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ /// The disposables.
+ void WhenNavigatedTo(IViewNavigationEventArgs e, CompositeDisposable disposables);
+
+ ///
+ /// Raises the event.
+ ///
+ ///
+ /// The instance containing the event data.
+ ///
+ void WhenNavigating(IViewNavigatingEventArgs e);
+}
diff --git a/src/ReactiveMarbles.View.Core/IRxNavBase.cs b/src/ReactiveMarbles.View.Core/IRxNavBase.cs
new file mode 100644
index 0000000..841cb44
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/IRxNavBase.cs
@@ -0,0 +1,16 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System.Reactive.Disposables;
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// interface for RxBase.
+///
+///
+public interface IRxNavBase : INotifiyRoutableView, ICancelable, IAmBuilt
+{
+}
diff --git a/src/ReactiveMarbles.View.Core/IViewRoutedViewModelHost.cs b/src/ReactiveMarbles.View.Core/IViewRoutedViewModelHost.cs
new file mode 100644
index 0000000..7710bf6
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/IViewRoutedViewModelHost.cs
@@ -0,0 +1,123 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System.Collections.ObjectModel;
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// IViewModel Routed ViewHost.
+///
+public interface IViewRoutedViewModelHost
+{
+ ///
+ /// Gets the navigation stack.
+ ///
+ ///
+ /// The navigation stack.
+ ///
+ ObservableCollection NavigationStack { get; }
+
+ ///
+ /// Gets the current view model.
+ ///
+ ///
+ /// The current view model.
+ ///
+ IObservable CurrentView { get; }
+
+ ///
+ /// Gets or sets a value indicating whether [navigate back is enabled].
+ ///
+ ///
+ /// true if [navigate back is enabled]; otherwise, false.
+ ///
+ bool CanNavigateBack { get; set; }
+
+ ///
+ /// Gets the can navigate back observable.
+ ///
+ ///
+ /// The can navigate back observable.
+ ///
+ IObservable CanNavigateBackObservable { get; }
+
+ ///
+ /// Gets or sets a value indicating whether [navigate back is enabled].
+ ///
+ ///
+ /// true if [navigate back is enabled]; otherwise, false.
+ ///
+ bool NavigateBackIsEnabled { get; set; }
+
+ ///
+ /// Gets or sets the name of the host.
+ ///
+ ///
+ /// The name of the host.
+ ///
+ string Name { get; set; }
+
+ ///
+ /// Gets a value indicating whether [requires setup].
+ ///
+ ///
+ /// true if [requires setup]; otherwise, false.
+ ///
+ bool RequiresSetup { get; }
+
+ ///
+ /// Clears the history.
+ ///
+ void ClearHistory();
+
+ ///
+ /// Setups this instance.
+ ///
+ void Setup();
+
+ ///
+ /// Navigates the specified contract.
+ ///
+ /// The Type.
+ /// The contract.
+ /// The parameter.
+ void Navigate(string? contract = null, object? parameter = null)
+ where T : class, IAmViewFor;
+
+ ///
+ /// Navigates the specified contract.
+ ///
+ /// The view model.
+ /// The parameter.
+ void Navigate(IAmViewFor viewModel, object? parameter = null);
+
+ ///
+ /// Navigates the and reset.
+ ///
+ /// The Type.
+ /// The contract.
+ /// The parameter.
+ void NavigateAndReset(string? contract = null, object? parameter = null)
+ where T : class, IAmViewFor;
+
+ ///
+ /// Navigates the and reset.
+ ///
+ /// The view model.
+ /// The parameter.
+ void NavigateAndReset(IAmViewFor viewModel, object? parameter = null);
+
+ ///
+ /// Navigates the back.
+ ///
+ /// The parameter.
+ void NavigateBack(object? parameter = null);
+
+ ///
+ /// Refreshes this instance.
+ ///
+ void Refresh();
+}
diff --git a/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigatingEventArgs.cs b/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigatingEventArgs.cs
new file mode 100644
index 0000000..7e0d022
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigatingEventArgs.cs
@@ -0,0 +1,19 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// IView Model Navigating EventArgs.
+///
+public interface IViewNavigatingEventArgs : IViewNavigationEventArgs
+{
+ ///
+ /// Gets or sets a value indicating whether this is cancel.
+ ///
+ ///
+ /// true if cancel; otherwise, false.
+ ///
+ bool Cancel { get; set; }
+}
diff --git a/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigationBaseEventArgs.cs b/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigationBaseEventArgs.cs
new file mode 100644
index 0000000..7d7d0be
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigationBaseEventArgs.cs
@@ -0,0 +1,37 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// IView Model Navigation Base Event Args.
+///
+public interface IViewNavigationBaseEventArgs
+{
+ ///
+ /// Gets from.
+ ///
+ ///
+ /// From.
+ ///
+ IRxNavBase? From { get; }
+
+ ///
+ /// Gets the navigation parameter.
+ ///
+ ///
+ /// The navigation parameter.
+ ///
+ object? NavigationParameter { get; }
+
+ ///
+ /// Gets to.
+ ///
+ ///
+ /// To.
+ ///
+ IRxNavBase? To { get; }
+}
diff --git a/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigationEventArgs.cs b/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigationEventArgs.cs
new file mode 100644
index 0000000..3e3610e
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/NavigationEvents/IViewNavigationEventArgs.cs
@@ -0,0 +1,37 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// I View Model Navigation EventArgs.
+///
+public interface IViewNavigationEventArgs : IViewNavigationBaseEventArgs
+{
+ ///
+ /// Gets or sets the name of the host.
+ ///
+ ///
+ /// The name of the host.
+ ///
+ string HostName { get; set; }
+
+ ///
+ /// Gets the type of the navigation.
+ ///
+ ///
+ /// The type of the navigation.
+ ///
+ NavigationType NavigationType { get; }
+
+ ///
+ /// Gets or sets the view.
+ ///
+ ///
+ /// The view.
+ ///
+ IAmViewFor? View { get; set; }
+}
diff --git a/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigatingEventArgs.cs b/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigatingEventArgs.cs
new file mode 100644
index 0000000..13d7d11
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigatingEventArgs.cs
@@ -0,0 +1,33 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System.Runtime.Serialization;
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// View Model Navigating Event Args.
+///
+///
+/// Initializes a new instance of the class.
+///
+/// From.
+/// To.
+/// Type of the nav.
+/// The view.
+/// The hostName.
+/// The parmeter.
+[DataContract]
+public class ViewNavigatingEventArgs(IRxNavBase? from, IRxNavBase? to, NavigationType navType, IAmViewFor? view, string hostName, object? parmeter = null)
+ : ViewNavigationEventArgs(from, to, navType, view, hostName, parmeter), IViewNavigatingEventArgs
+{
+ ///
+ /// Gets or sets a value indicating whether this
+ /// is canceled.
+ ///
+ /// true if cancel; otherwise, false.
+ [DataMember]
+ public bool Cancel { get; set; }
+}
diff --git a/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigationBaseEventArgs.cs b/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigationBaseEventArgs.cs
new file mode 100644
index 0000000..3862fca
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigationBaseEventArgs.cs
@@ -0,0 +1,38 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System.Runtime.Serialization;
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// View Model Navigation Base Event Args.
+///
+///
+[DataContract]
+public abstract class ViewNavigationBaseEventArgs
+ : EventArgs, IViewNavigationBaseEventArgs
+{
+ ///
+ /// Gets or sets where is Navigating from.
+ ///
+ /// From.
+ [DataMember]
+ public IRxNavBase? From { get; protected set; }
+
+ ///
+ /// Gets or sets the navigation parameter.
+ ///
+ /// The navigation parameter.
+ [DataMember]
+ public object? NavigationParameter { get; protected set; }
+
+ ///
+ /// Gets or sets where is Navigating to.
+ ///
+ /// To.
+ [DataMember]
+ public IRxNavBase? To { get; protected set; }
+}
diff --git a/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigationEventArgs.cs b/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigationEventArgs.cs
new file mode 100644
index 0000000..06714e7
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/NavigationEvents/ViewNavigationEventArgs.cs
@@ -0,0 +1,55 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System.Runtime.Serialization;
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// View Model Navigation EventArgs.
+///
+[DataContract]
+public class ViewNavigationEventArgs : ViewNavigationBaseEventArgs, IViewNavigationEventArgs
+{
+ /// Initializes a new instance of the class.
+ /// From.
+ /// To.
+ /// Type of the nav.
+ /// The view.
+ /// The Hostname.
+ /// The parmeter.
+ public ViewNavigationEventArgs(IRxNavBase? from, IRxNavBase? to, NavigationType navType, IAmViewFor? view, string hostName, object? parmeter = null)
+ {
+ From = from;
+ To = to;
+ View = view;
+ NavigationType = navType;
+ NavigationParameter = parmeter;
+ HostName = hostName;
+ }
+
+ ///
+ /// Gets or sets the name of the host.
+ ///
+ ///
+ /// The name of the host.
+ ///
+ [DataMember]
+ public string HostName { get; set; }
+
+ ///
+ /// Gets or sets the type of the navigation.
+ ///
+ /// The type of the navigation.
+ [DataMember]
+ public NavigationType NavigationType { get; protected set; }
+
+ ///
+ /// Gets or sets the view.
+ ///
+ /// The view.
+ [DataMember]
+ public IAmViewFor? View { get; set; }
+}
diff --git a/src/ReactiveMarbles.View.Core/ReactiveMarbles.View.Core.csproj b/src/ReactiveMarbles.View.Core/ReactiveMarbles.View.Core.csproj
new file mode 100644
index 0000000..333da19
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/ReactiveMarbles.View.Core.csproj
@@ -0,0 +1,22 @@
+
+
+
+ netstandard2.0;net6.0;net7.0;net8.0;net7.0-macos;net8.0-macos;net7.0-tvos;net8.0-tvos;$(MauiTargetFrameworks)
+ $(TargetFrameworks);net462;net472;net6.0-windows10.0.19041.0;$(MauiWinTargetFrameworks)
+ enable
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ReactiveMarbles.View.Core/RxNavBase.cs b/src/ReactiveMarbles.View.Core/RxNavBase.cs
new file mode 100644
index 0000000..e30e906
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/RxNavBase.cs
@@ -0,0 +1,84 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using System.Reactive.Disposables;
+
+namespace ReactiveMarbles.View.Core;
+
+///
+/// Rx Object.
+///
+///
+///
+public abstract class RxNavBase : Mvvm.RxObject, IRxNavBase
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected RxNavBase()
+ {
+ }
+
+ ///
+ /// Gets the URL path segment.
+ ///
+ ///
+ /// The URL path segment.
+ ///
+ public string? Name => GetType().FullName;
+
+ ///
+ /// Gets a value indicating whether this instance is disposed.
+ ///
+ /// true if this instance is disposed; otherwise, false.
+ public bool IsDisposed => Disposables?.IsDisposed == true;
+
+ ///
+ /// Gets the disposables.
+ ///
+ ///
+ /// The disposables.
+ ///
+ protected CompositeDisposable Disposables { get; } = new CompositeDisposable();
+
+ ///
+ /// Performs application-defined tasks associated with freeing, releasing, or resetting
+ /// unmanaged resources.
+ ///
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ public virtual void WhenNavigatedFrom(IViewNavigationEventArgs e)
+ {
+ }
+
+ ///
+ public virtual void WhenNavigatedTo(IViewNavigationEventArgs e, CompositeDisposable disposables)
+ {
+ }
+
+ ///
+ public virtual void WhenNavigating(IViewNavigatingEventArgs e)
+ {
+ }
+
+ ///
+ /// Releases unmanaged and - optionally - managed resources.
+ ///
+ ///
+ /// true to release both managed and unmanaged resources; false to release only
+ /// unmanaged resources.
+ ///
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!IsDisposed && disposing)
+ {
+ Disposables?.Dispose();
+ }
+ }
+}
diff --git a/src/ReactiveMarbles.View.Core/ServiceLocatorMixins.cs b/src/ReactiveMarbles.View.Core/ServiceLocatorMixins.cs
new file mode 100644
index 0000000..e139dbb
--- /dev/null
+++ b/src/ReactiveMarbles.View.Core/ServiceLocatorMixins.cs
@@ -0,0 +1,124 @@
+// Copyright (c) 2019-2023 ReactiveUI Association Incorporated. All rights reserved.
+// ReactiveUI Association Incorporated licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for full license information.
+
+using ReactiveMarbles.View.Core;
+using ReactiveMarbles.ViewModel.Core;
+
+namespace ReactiveMarbles.Locator;
+
+///
+/// ServiceLocatorMixins.
+///
+public static class ServiceLocatorMixins
+{
+ ///
+ /// Adds the navigation view.
+ ///
+ /// The type of the view model.
+ /// The type of the view.
+ /// The service locator.
+ public static void AddNavigationView(this IServiceLocator serviceLocator)
+ where TView : class, IAmViewFor, new()
+ where TViewModel : class, IRxNavBase
+ {
+ if (serviceLocator == null)
+ {
+ throw new ArgumentNullException(nameof(serviceLocator));
+ }
+
+ serviceLocator.AddService