Browse Source

Moved layout manager from service locator to ILayoutRoot

Nikita Tsukanov 8 years ago
parent
commit
eb6bfd3de8

+ 0 - 1
src/Avalonia.Controls/Application.cs

@@ -175,7 +175,6 @@ namespace Avalonia
                 .Bind<IInputManager>().ToConstant(InputManager)
                 .Bind<IKeyboardNavigationHandler>().ToTransient<KeyboardNavigationHandler>()
                 .Bind<IStyler>().ToConstant(_styler)
-                .Bind<ILayoutManager>().ToSingleton<LayoutManager>()
                 .Bind<IApplicationLifecycle>().ToConstant(this)
                 .Bind<IScheduler>().ToConstant(AvaloniaScheduler.Instance);
         }

+ 1 - 1
src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs

@@ -26,7 +26,7 @@ namespace Avalonia.Controls.Embedding
         {
             EnsureInitialized();
             ApplyTemplate();
-            LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+            LayoutManager.ExecuteInitialLayoutPass(this);
         }
 
         private void EnsureInitialized()

+ 1 - 1
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@@ -510,7 +510,7 @@ namespace Avalonia.Controls.Presenters
                 }
 
                 var container = generator.ContainerFromIndex(index);
-                var layoutManager = LayoutManager.Instance;
+                var layoutManager = (Owner.GetVisualRoot() as ILayoutRoot)?.LayoutManager;
 
                 // We need to do a layout here because it's possible that the container we moved to
                 // is only partially visible due to differing item sizes. If the container is only 

+ 14 - 1
src/Avalonia.Controls/TopLevel.cs

@@ -46,6 +46,7 @@ namespace Avalonia.Controls
         private readonly IApplicationLifecycle _applicationLifecycle;
         private readonly IPlatformRenderInterface _renderInterface;
         private Size _clientSize;
+        private ILayoutManager _layoutManager;
 
         /// <summary>
         /// Initializes static members of the <see cref="TopLevel"/> class.
@@ -133,6 +134,18 @@ namespace Avalonia.Controls
             protected set { SetAndRaise(ClientSizeProperty, ref _clientSize, value); }
         }
 
+        protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager();
+
+        public ILayoutManager LayoutManager
+        {
+            get
+            {
+                if (_layoutManager == null)
+                    _layoutManager = CreateLayoutManager();
+                return _layoutManager;
+            }
+        }
+
         /// <summary>
         /// Gets the platform-specific window implementation.
         /// </summary>
@@ -245,7 +258,7 @@ namespace Avalonia.Controls
             ClientSize = clientSize;
             Width = clientSize.Width;
             Height = clientSize.Height;
-            LayoutManager.Instance.ExecuteLayoutPass();
+            LayoutManager.ExecuteLayoutPass();
             Renderer?.Resized(clientSize);
         }
 

+ 2 - 2
src/Avalonia.Controls/Window.cs

@@ -247,7 +247,7 @@ namespace Avalonia.Controls
 
             EnsureInitialized();
             IsVisible = true;
-            LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+            LayoutManager.ExecuteInitialLayoutPass(this);
 
             using (BeginAutoSizing())
             {
@@ -286,7 +286,7 @@ namespace Avalonia.Controls
 
             EnsureInitialized();
             IsVisible = true;
-            LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+            LayoutManager.ExecuteInitialLayoutPass(this);
 
             using (BeginAutoSizing())
             {

+ 2 - 2
src/Avalonia.Controls/WindowBase.cs

@@ -136,7 +136,7 @@ namespace Avalonia.Controls
             {
                 EnsureInitialized();
                 IsVisible = true;
-                LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+                LayoutManager.ExecuteInitialLayoutPass(this);
                 PlatformImpl?.Show();
             }
             finally
@@ -215,7 +215,7 @@ namespace Avalonia.Controls
                 Height = clientSize.Height;
             }
             ClientSize = clientSize;
-            LayoutManager.Instance.ExecuteLayoutPass();
+            LayoutManager.ExecuteLayoutPass();
             Renderer?.Resized(clientSize);
         }
 

+ 5 - 0
src/Avalonia.Layout/ILayoutRoot.cs

@@ -22,5 +22,10 @@ namespace Avalonia.Layout
         /// The scaling factor to use in layout.
         /// </summary>
         double LayoutScaling { get; }
+
+        /// <summary>
+        /// Associated instance of layout manager
+        /// </summary>
+        ILayoutManager LayoutManager { get; }
     }
 }

+ 0 - 5
src/Avalonia.Layout/LayoutManager.cs

@@ -19,11 +19,6 @@ namespace Avalonia.Layout
         private bool _queued;
         private bool _running;
 
-        /// <summary>
-        /// Gets the layout manager.
-        /// </summary>
-        public static ILayoutManager Instance => AvaloniaLocator.Current.GetService<ILayoutManager>();
-
         /// <inheritdoc/>
         public void InvalidateMeasure(ILayoutable control)
         {

+ 11 - 2
src/Avalonia.Layout/Layoutable.cs

@@ -378,7 +378,7 @@ namespace Avalonia.Layout
 
                 IsMeasureValid = false;
                 IsArrangeValid = false;
-                LayoutManager.Instance?.InvalidateMeasure(this);
+                (VisualRoot as ILayoutRoot)?.LayoutManager.InvalidateMeasure(this);
                 InvalidateVisual();
             }
         }
@@ -393,7 +393,7 @@ namespace Avalonia.Layout
                 Logger.Verbose(LogArea.Layout, this, "Invalidated arrange");
 
                 IsArrangeValid = false;
-                LayoutManager.Instance?.InvalidateArrange(this);
+                (VisualRoot as ILayoutRoot)?.LayoutManager?.InvalidateArrange(this);
                 InvalidateVisual();
             }
         }
@@ -620,6 +620,15 @@ namespace Avalonia.Layout
             base.OnVisualParentChanged(oldParent, newParent);
         }
 
+        protected override void OnAttachedToVisualTreeCore(VisualTreeAttachmentEventArgs e)
+        {
+            base.OnAttachedToVisualTreeCore(e);
+            if(!IsMeasureValid)
+                (VisualRoot as ILayoutRoot)?.LayoutManager.InvalidateMeasure(this);
+            else if (!IsArrangeValid)
+                (VisualRoot as ILayoutRoot)?.LayoutManager.InvalidateArrange(this);
+        }
+
         /// <summary>
         /// Calls <see cref="InvalidateMeasure"/> on the control on which a property changed.
         /// </summary>

+ 9 - 3
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs

@@ -12,6 +12,7 @@ using Avalonia.Layout;
 using Avalonia.Platform;
 using Avalonia.Rendering;
 using Avalonia.UnitTests;
+using Avalonia.VisualTree;
 using Xunit;
 
 namespace Avalonia.Controls.UnitTests.Presenters
@@ -219,7 +220,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
         [Fact]
         public void Changing_VirtualizationMode_None_To_Simple_Should_Add_Correct_Number_Of_Controls()
         {
-            using (UnitTestApplication.Start(TestServices.RealLayoutManager))
+            using (UnitTestApplication.Start(new TestServices()))
             {
                 var target = CreateTarget(mode: ItemVirtualizationMode.None);
                 var scroll = (ScrollContentPresenter)target.Parent;
@@ -237,7 +238,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
                 };
 
                 target.VirtualizationMode = ItemVirtualizationMode.Simple;
-                LayoutManager.Instance.ExecuteLayoutPass();
+                ((ILayoutRoot)scroll.GetVisualRoot()).LayoutManager.ExecuteLayoutPass();
 
                 Assert.Equal(10, target.Panel.Children.Count);
             }
@@ -313,11 +314,16 @@ namespace Avalonia.Controls.UnitTests.Presenters
             });
         }
 
-        private class TestScroller : ScrollContentPresenter, IRenderRoot
+        private class TestScroller : ScrollContentPresenter, IRenderRoot, ILayoutRoot
         {
             public IRenderer Renderer { get; }
             public Size ClientSize { get; }
 
+            public Size MaxClientSize => Size.Infinity;
+
+            public double LayoutScaling => 1;
+
+            public ILayoutManager LayoutManager { get; } = new LayoutManager();
             public IRenderTarget CreateRenderTarget()
             {
                 throw new NotImplementedException();

+ 5 - 5
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs

@@ -564,11 +564,10 @@ namespace Avalonia.Controls.UnitTests.Presenters
         [Fact]
         public void Scrolling_To_Item_In_Zero_Sized_Presenter_Doesnt_Throw()
         {
-            using (UnitTestApplication.Start(TestServices.RealLayoutManager))
+            using (UnitTestApplication.Start(new TestServices()))
             {
                 var target = CreateTarget(itemCount: 10);
                 var items = (IList<string>)target.Items;
-
                 target.ApplyTemplate();
                 target.Measure(Size.Empty);
                 target.Arrange(Rect.Empty);
@@ -757,7 +756,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             [Fact]
             public void GetControlInDirection_Down_Should_Scroll_If_Partially_Visible()
             {
-                using (UnitTestApplication.Start(TestServices.RealLayoutManager))
+                using (UnitTestApplication.Start(new TestServices()))
                 {
                     var target = CreateTarget();
                     var scroller = (ScrollContentPresenter)target.Parent;
@@ -778,7 +777,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             [Fact]
             public void GetControlInDirection_Up_Should_Scroll_If_Partially_Visible_Item_Is_Currently_Shown()
             {
-                using (UnitTestApplication.Start(TestServices.RealLayoutManager))
+                using (UnitTestApplication.Start(new TestServices()))
                 {
                     var target = CreateTarget();
                     var scroller = (ScrollContentPresenter)target.Parent;
@@ -869,7 +868,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             [Fact]
             public void GetControlInDirection_Right_Should_Scroll_If_Partially_Visible()
             {
-                using (UnitTestApplication.Start(TestServices.RealLayoutManager))
+                using (UnitTestApplication.Start(new TestServices()))
                 {
                     var target = CreateTarget(orientation: Orientation.Horizontal);
                     var scroller = (ScrollContentPresenter)target.Parent;
@@ -1008,6 +1007,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             };
 
             scroller.UpdateChild();
+            new TestRoot().Child = scroller;
 
             return result;
         }

+ 0 - 1
tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs

@@ -270,7 +270,6 @@ namespace Avalonia.Controls.UnitTests.Primitives
             var renderInterface = new Mock<IPlatformRenderInterface>();
 
             AvaloniaLocator.CurrentMutable
-                .Bind<ILayoutManager>().ToTransient<LayoutManager>()
                 .Bind<IGlobalStyles>().ToFunc(() => globalStyles.Object)
                 .Bind<IWindowingPlatform>().ToConstant(new WindowingPlatformMock())
                 .Bind<IStyler>().ToTransient<Styler>()

+ 11 - 6
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

@@ -65,15 +65,16 @@ namespace Avalonia.Controls.UnitTests
         [Fact]
         public void Layout_Pass_Should_Not_Be_Automatically_Scheduled()
         {
-            var services = TestServices.StyledWindow.With(layoutManager: Mock.Of<ILayoutManager>());
+            var services = TestServices.StyledWindow;
 
             using (UnitTestApplication.Start(services))
             {
                 var impl = new Mock<ITopLevelImpl>();
-                var target = new TestTopLevel(impl.Object);
+                
+                var target = new TestTopLevel(impl.Object, Mock.Of<ILayoutManager>());
 
                 // The layout pass should be scheduled by the derived class.
-                var layoutManagerMock = Mock.Get(LayoutManager.Instance);
+                var layoutManagerMock = Mock.Get(target.LayoutManager);
                 layoutManagerMock.Verify(x => x.ExecuteLayoutPass(), Times.Never);
             }
         }
@@ -98,7 +99,7 @@ namespace Avalonia.Controls.UnitTests
                     }
                 };
 
-                LayoutManager.Instance.ExecuteInitialLayoutPass(target);
+                target.LayoutManager.ExecuteInitialLayoutPass(target);
 
                 Assert.Equal(new Rect(0, 0, 321, 432), target.Bounds);
             }
@@ -113,7 +114,7 @@ namespace Avalonia.Controls.UnitTests
                 impl.Setup(x => x.ClientSize).Returns(new Size(123, 456));
 
                 var target = new TestTopLevel(impl.Object);
-                LayoutManager.Instance.ExecuteLayoutPass();
+                target.LayoutManager.ExecuteLayoutPass();
 
                 Assert.Equal(double.NaN, target.Width);
                 Assert.Equal(double.NaN, target.Height);
@@ -222,13 +223,17 @@ namespace Avalonia.Controls.UnitTests
 
         private class TestTopLevel : TopLevel
         {
+            private readonly ILayoutManager _layoutManager;
             public bool IsClosed { get; private set; }
 
-            public TestTopLevel(ITopLevelImpl impl)
+            public TestTopLevel(ITopLevelImpl impl, ILayoutManager layoutManager = null)
                 : base(impl)
             {
+                _layoutManager = layoutManager ?? new LayoutManager();
             }
 
+            protected override ILayoutManager CreateLayoutManager() => _layoutManager;
+
             protected override void HandleApplicationExiting()
             {
                 base.HandleApplicationExiting();

+ 1 - 1
tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs

@@ -38,7 +38,7 @@ namespace Avalonia.Controls.UnitTests
                     IsVisible = true,
                 };
 
-                LayoutManager.Instance.ExecuteInitialLayoutPass(target);
+                target.LayoutManager.ExecuteInitialLayoutPass(target);
 
                 Mock.Get(impl).Verify(x => x.Resize(new Size(321, 432)));
             }

+ 3 - 4
tests/Avalonia.Layout.UnitTests/FullLayoutTests.cs

@@ -56,11 +56,11 @@ namespace Avalonia.Layout.UnitTests
                 };
 
                 window.Show();
-                LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                window.LayoutManager.ExecuteInitialLayoutPass(window);
 
                 Assert.Equal(new Size(400, 400), border.Bounds.Size);
                 textBlock.Width = 200;
-                LayoutManager.Instance.ExecuteLayoutPass();
+                window.LayoutManager.ExecuteLayoutPass();
 
                 Assert.Equal(new Size(200, 400), border.Bounds.Size);
             }
@@ -98,7 +98,7 @@ namespace Avalonia.Layout.UnitTests
                 };
 
                 window.Show();
-                LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                window.LayoutManager.ExecuteInitialLayoutPass(window);
 
                 Assert.Equal(new Size(800, 600), window.Bounds.Size);
                 Assert.Equal(new Size(200, 200), scrollViewer.Bounds.Size);
@@ -186,7 +186,6 @@ namespace Avalonia.Layout.UnitTests
                 .Bind<IAssetLoader>().ToConstant(new AssetLoader())
                 .Bind<IInputManager>().ToConstant(new Mock<IInputManager>().Object)
                 .Bind<IGlobalStyles>().ToConstant(globalStyles.Object)
-                .Bind<ILayoutManager>().ToConstant(new LayoutManager())
                 .Bind<IRuntimePlatform>().ToConstant(new AppBuilder().RuntimePlatform)
                 .Bind<IPlatformRenderInterface>().ToConstant(renderInterface.Object)
                 .Bind<IStyler>().ToConstant(new Styler())

+ 4 - 7
tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs

@@ -11,12 +11,9 @@ namespace Avalonia.Layout.UnitTests
         [Fact]
         public void Invalidating_Child_Should_Remeasure_Parent()
         {
-            var layoutManager = new LayoutManager();
-
             using (AvaloniaLocator.EnterScope())
             {
-                AvaloniaLocator.CurrentMutable.Bind<ILayoutManager>().ToConstant(layoutManager);
-
+                
                 Border border;
                 StackPanel panel;
 
@@ -30,14 +27,14 @@ namespace Avalonia.Layout.UnitTests
                     }
                     }
                 };
-
-                layoutManager.ExecuteInitialLayoutPass(root);
+                
+                root.LayoutManager.ExecuteInitialLayoutPass(root);
                 Assert.Equal(new Size(0, 0), root.DesiredSize);
 
                 border.Width = 100;
                 border.Height = 100;
 
-                layoutManager.ExecuteLayoutPass();
+                root.LayoutManager.ExecuteLayoutPass();
                 Assert.Equal(new Size(100, 100), panel.DesiredSize);
             }                
         }

+ 18 - 1
tests/Avalonia.Layout.UnitTests/TestLayoutRoot.cs

@@ -2,10 +2,12 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 using Avalonia.Controls;
+using Avalonia.Platform;
+using Avalonia.Rendering;
 
 namespace Avalonia.Layout.UnitTests
 {
-    internal class TestLayoutRoot : Decorator, ILayoutRoot
+    internal class TestLayoutRoot : Decorator, ILayoutRoot, IRenderRoot
     {
         public TestLayoutRoot()
         {
@@ -18,7 +20,22 @@ namespace Avalonia.Layout.UnitTests
             set;
         }
 
+        public IRenderer Renderer => null;
+
+        public IRenderTarget CreateRenderTarget() => null;
+
+        public void Invalidate(Rect rect)
+        {
+        }
+
+        public Point PointToClient(Point point) => point;
+
+        public Point PointToScreen(Point point) => point;
+
         public Size MaxClientSize => Size.Infinity;
         public double LayoutScaling => 1;
+
+        public ILayoutManager LayoutManager { get; set; } = new LayoutManager();
+        
     }
 }

+ 14 - 14
tests/Avalonia.LeakTests/ControlTests.cs

@@ -42,12 +42,12 @@ namespace Avalonia.LeakTests
                     window.Show();
 
                     // Do a layout and make sure that Canvas gets added to visual tree.
-                    LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                    window.LayoutManager.ExecuteInitialLayoutPass(window);
                     Assert.IsType<Canvas>(window.Presenter.Child);
 
                     // Clear the content and ensure the Canvas is removed.
                     window.Content = null;
-                    LayoutManager.Instance.ExecuteLayoutPass();
+                    window.LayoutManager.ExecuteLayoutPass();
                     Assert.Null(window.Presenter.Child);
 
                     return window;
@@ -78,13 +78,13 @@ namespace Avalonia.LeakTests
                     window.Show();
 
                     // Do a layout and make sure that Canvas gets added to visual tree.
-                    LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                    window.LayoutManager.ExecuteInitialLayoutPass(window);
                     Assert.IsType<Canvas>(window.Find<Canvas>("foo"));
                     Assert.IsType<Canvas>(window.Presenter.Child);
 
                     // Clear the content and ensure the Canvas is removed.
                     window.Content = null;
-                    LayoutManager.Instance.ExecuteLayoutPass();
+                    window.LayoutManager.ExecuteLayoutPass();
                     Assert.Null(window.Presenter.Child);
 
                     return window;
@@ -116,13 +116,13 @@ namespace Avalonia.LeakTests
 
                     // Do a layout and make sure that ScrollViewer gets added to visual tree and its 
                     // template applied.
-                    LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                    window.LayoutManager.ExecuteInitialLayoutPass(window);
                     Assert.IsType<ScrollViewer>(window.Presenter.Child);
                     Assert.IsType<Canvas>(((ScrollViewer)window.Presenter.Child).Presenter.Child);
 
                     // Clear the content and ensure the ScrollViewer is removed.
                     window.Content = null;
-                    LayoutManager.Instance.ExecuteLayoutPass();
+                    window.LayoutManager.ExecuteLayoutPass();
                     Assert.Null(window.Presenter.Child);
 
                     return window;
@@ -153,13 +153,13 @@ namespace Avalonia.LeakTests
 
                     // Do a layout and make sure that TextBox gets added to visual tree and its 
                     // template applied.
-                    LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                    window.LayoutManager.ExecuteInitialLayoutPass(window);
                     Assert.IsType<TextBox>(window.Presenter.Child);
                     Assert.NotEqual(0, window.Presenter.Child.GetVisualChildren().Count());
 
                     // Clear the content and ensure the TextBox is removed.
                     window.Content = null;
-                    LayoutManager.Instance.ExecuteLayoutPass();
+                    window.LayoutManager.ExecuteLayoutPass();
                     Assert.Null(window.Presenter.Child);
 
                     return window;
@@ -197,14 +197,14 @@ namespace Avalonia.LeakTests
 
                     // Do a layout and make sure that TextBox gets added to visual tree and its 
                     // Text property set.
-                    LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                    window.LayoutManager.ExecuteInitialLayoutPass(window);
                     Assert.IsType<TextBox>(window.Presenter.Child);
                     Assert.Equal("foo", ((TextBox)window.Presenter.Child).Text);
 
                     // Clear the content and DataContext and ensure the TextBox is removed.
                     window.Content = null;
                     window.DataContext = null;
-                    LayoutManager.Instance.ExecuteLayoutPass();
+                    window.LayoutManager.ExecuteLayoutPass();
                     Assert.Null(window.Presenter.Child);
 
                     return window;
@@ -235,7 +235,7 @@ namespace Avalonia.LeakTests
 
                 // Do a layout and make sure that TextBox gets added to visual tree and its 
                 // template applied.
-                LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                window.LayoutManager.ExecuteInitialLayoutPass(window);
                 Assert.Same(textBox, window.Presenter.Child);
 
                 // Get the border from the TextBox template.
@@ -247,7 +247,7 @@ namespace Avalonia.LeakTests
 
                 // Clear the content and ensure the TextBox is removed.
                 window.Content = null;
-                LayoutManager.Instance.ExecuteLayoutPass();
+                window.LayoutManager.ExecuteLayoutPass();
                 Assert.Null(window.Presenter.Child);
 
                 // Check that the TextBox has no subscriptions to its Classes collection.
@@ -289,12 +289,12 @@ namespace Avalonia.LeakTests
                     window.Show();
 
                     // Do a layout and make sure that TreeViewItems get realized.
-                    LayoutManager.Instance.ExecuteInitialLayoutPass(window);
+                    window.LayoutManager.ExecuteInitialLayoutPass(window);
                     Assert.Equal(1, target.ItemContainerGenerator.Containers.Count());
 
                     // Clear the content and ensure the TreeView is removed.
                     window.Content = null;
-                    LayoutManager.Instance.ExecuteLayoutPass();
+                    window.LayoutManager.ExecuteLayoutPass();
                     Assert.Null(window.Presenter.Child);
 
                     return window;

+ 1 - 1
tests/Avalonia.UnitTests/TestRoot.cs

@@ -47,7 +47,7 @@ namespace Avalonia.UnitTests
 
         public double LayoutScaling => 1;
 
-        public ILayoutManager LayoutManager => AvaloniaLocator.Current.GetService<ILayoutManager>();
+        public ILayoutManager LayoutManager { get; set; } = new LayoutManager();
 
         public IRenderTarget RenderTarget => null;
 

+ 1 - 10
tests/Avalonia.UnitTests/TestServices.cs

@@ -21,7 +21,6 @@ namespace Avalonia.UnitTests
     {
         public static readonly TestServices StyledWindow = new TestServices(
             assetLoader: new AssetLoader(),
-            layoutManager: new LayoutManager(),
             platform: new AppBuilder().RuntimePlatform,
             renderer: (_, __) => Mock.Of<IRenderer>(),
             renderInterface: CreateRenderInterfaceMock(),
@@ -51,10 +50,7 @@ namespace Avalonia.UnitTests
             focusManager: new FocusManager(),
             keyboardDevice: () => new KeyboardDevice(),
             inputManager: new InputManager());
-
-        public static readonly TestServices RealLayoutManager = new TestServices(
-            layoutManager: new LayoutManager());
-
+        
         public static readonly TestServices RealStyler = new TestServices(
             styler: new Styler());
 
@@ -63,7 +59,6 @@ namespace Avalonia.UnitTests
             IFocusManager focusManager = null,
             IInputManager inputManager = null,
             Func<IKeyboardDevice> keyboardDevice = null,
-            ILayoutManager layoutManager = null,
             IRuntimePlatform platform = null,
             Func<IRenderRoot, IRenderLoop, IRenderer> renderer = null,
             IPlatformRenderInterface renderInterface = null,
@@ -79,7 +74,6 @@ namespace Avalonia.UnitTests
             FocusManager = focusManager;
             InputManager = inputManager;
             KeyboardDevice = keyboardDevice;
-            LayoutManager = layoutManager;
             Platform = platform;
             Renderer = renderer;
             RenderInterface = renderInterface;
@@ -96,7 +90,6 @@ namespace Avalonia.UnitTests
         public IInputManager InputManager { get; }
         public IFocusManager FocusManager { get; }
         public Func<IKeyboardDevice> KeyboardDevice { get; }
-        public ILayoutManager LayoutManager { get; }
         public IRuntimePlatform Platform { get; }
         public Func<IRenderRoot, IRenderLoop, IRenderer> Renderer { get; }
         public IPlatformRenderInterface RenderInterface { get; }
@@ -113,7 +106,6 @@ namespace Avalonia.UnitTests
             IFocusManager focusManager = null,
             IInputManager inputManager = null,
             Func<IKeyboardDevice> keyboardDevice = null,
-            ILayoutManager layoutManager = null,
             IRuntimePlatform platform = null,
             Func<IRenderRoot, IRenderLoop, IRenderer> renderer = null,
             IPlatformRenderInterface renderInterface = null,
@@ -131,7 +123,6 @@ namespace Avalonia.UnitTests
                 focusManager: focusManager ?? FocusManager,
                 inputManager: inputManager ?? InputManager,
                 keyboardDevice: keyboardDevice ?? KeyboardDevice,
-                layoutManager: layoutManager ?? LayoutManager,
                 platform: platform ?? Platform,
                 renderer: renderer ?? Renderer,
                 renderInterface: renderInterface ?? RenderInterface,

+ 1 - 1
tests/Avalonia.UnitTests/TestTemplatedRoot.cs

@@ -39,7 +39,7 @@ namespace Avalonia.UnitTests
 
         public double LayoutScaling => 1;
 
-        public ILayoutManager LayoutManager => AvaloniaLocator.Current.GetService<ILayoutManager>();
+        public ILayoutManager LayoutManager { get; set; } = new LayoutManager();
 
         public IRenderTarget RenderTarget => null;
 

+ 0 - 1
tests/Avalonia.UnitTests/UnitTestApplication.cs

@@ -49,7 +49,6 @@ namespace Avalonia.UnitTests
                 .BindToSelf<IGlobalStyles>(this)
                 .Bind<IInputManager>().ToConstant(Services.InputManager)
                 .Bind<IKeyboardDevice>().ToConstant(Services.KeyboardDevice?.Invoke())
-                .Bind<ILayoutManager>().ToConstant(Services.LayoutManager)
                 .Bind<IRuntimePlatform>().ToConstant(Services.Platform)
                 .Bind<IRendererFactory>().ToConstant(new RendererFactory(Services.Renderer))
                 .Bind<IPlatformRenderInterface>().ToConstant(Services.RenderInterface)