Skip to content

Commit 522170e

Browse files
authored
Merge pull request #1353 from reactiveui/develop
+semver: feature
2 parents 4f75505 + 7f6d660 commit 522170e

File tree

3 files changed

+73
-12
lines changed

3 files changed

+73
-12
lines changed

src/ReactiveUI.Tests/ViewLocatorTests.cs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using ReactiveUI;
32
using Splat;
43
using Xunit;
54

@@ -72,6 +71,29 @@ object IViewFor.ViewModel
7271
public IFooViewModel ViewModel { get; set; }
7372
}
7473

74+
public interface StrangeInterfaceNotFollowingConvention { }
75+
76+
public class StrangeClassNotFollowingConvention : StrangeInterfaceNotFollowingConvention { }
77+
78+
public interface IRoutableFooViewModel : IRoutableViewModel { }
79+
80+
public class RoutableFooViewModel : ReactiveObject, IRoutableFooViewModel
81+
{
82+
public IScreen HostScreen { get; set; }
83+
public string UrlPathSegment { get; set; }
84+
}
85+
86+
public class RoutableFooView : IViewFor<IRoutableFooViewModel>
87+
{
88+
object IViewFor.ViewModel
89+
{
90+
get { return ViewModel; }
91+
set { ViewModel = (IRoutableFooViewModel)value; }
92+
}
93+
public IRoutableFooViewModel ViewModel { get; set; }
94+
}
95+
96+
7597
public class DefaultViewLocatorTests
7698
{
7799
[Fact]
@@ -332,5 +354,40 @@ public void AnErrorIsRaisedIfTheCreationOfTheViewFails()
332354
Assert.Equal("This is a test failure.", ex.Message);
333355
}
334356
}
357+
358+
[Fact]
359+
public void WithOddInterfaceNameDoesntThrowException()
360+
{
361+
var resolver = new ModernDependencyResolver();
362+
363+
resolver.InitializeSplat();
364+
resolver.InitializeReactiveUI();
365+
366+
using (resolver.WithResolver()) {
367+
var fixture = new DefaultViewLocator();
368+
369+
var vm = new StrangeClassNotFollowingConvention();
370+
371+
fixture.ResolveView((StrangeInterfaceNotFollowingConvention)vm);
372+
}
373+
}
374+
375+
[Fact]
376+
public void CanResolveViewFromViewModelWithIRoutableViewModelType()
377+
{
378+
var resolver = new ModernDependencyResolver();
379+
380+
resolver.InitializeSplat();
381+
resolver.InitializeReactiveUI();
382+
resolver.Register(() => new RoutableFooView(), typeof(IViewFor<IRoutableFooViewModel>));
383+
384+
using (resolver.WithResolver()) {
385+
var fixture = new DefaultViewLocator();
386+
var vm = new RoutableFooViewModel();
387+
388+
var result = fixture.ResolveView<IRoutableViewModel>(vm);
389+
Assert.IsType<RoutableFooView>(result);
390+
}
391+
}
335392
}
336393
}

src/ReactiveUI/ViewLocator.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public DefaultViewLocator(Func<string, string> viewModelToViewFunc = null)
7777
/// </item>
7878
/// <item>
7979
/// <description>
80-
/// Repeat steps 1 and 2 with the type resolved from the modified name.
80+
/// Repeat steps 1-4 with the type resolved from the modified name.
8181
/// </description>
8282
/// </item>
8383
/// </list>
@@ -107,8 +107,13 @@ public IViewFor ResolveView<T>(T viewModel, string contract = null)
107107
return view;
108108
}
109109

110-
var toggledType = ToggleViewModelType(viewModel);
111-
view = this.AttemptViewResolutionFor(toggledType, contract);
110+
view = this.AttemptViewResolutionFor(ToggleViewModelType(viewModel.GetType()), contract);
111+
112+
if (view != null) {
113+
return view;
114+
}
115+
116+
view = this.AttemptViewResolutionFor(ToggleViewModelType(typeof(T)), contract);
112117

113118
if (view != null) {
114119
return view;
@@ -120,6 +125,7 @@ public IViewFor ResolveView<T>(T viewModel, string contract = null)
120125

121126
private IViewFor AttemptViewResolutionFor(Type viewModelType, string contract)
122127
{
128+
if (viewModelType == null) return null;
123129
var viewModelTypeName = viewModelType.AssemblyQualifiedName;
124130
var proposedViewTypeName = this.ViewModelToViewFunc(viewModelTypeName);
125131
var view = this.AttemptViewResolution(proposedViewTypeName, contract);
@@ -169,9 +175,8 @@ private IViewFor AttemptViewResolution(string viewTypeName, string contract)
169175
}
170176
}
171177

172-
private static Type ToggleViewModelType<T>(T viewModel)
178+
private static Type ToggleViewModelType(Type viewModelType)
173179
{
174-
var viewModelType = typeof(T);
175180
var viewModelTypeName = viewModelType.AssemblyQualifiedName;
176181

177182
if (viewModelType.GetTypeInfo().IsInterface) {

src/ReactiveUI/Xaml/ViewModelViewHost.cs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,17 @@ public ViewModelViewHost()
104104
var view = viewLocator.ResolveView(x.ViewModel, x.Contract) ?? viewLocator.ResolveView(x.ViewModel, null);
105105

106106
if (view == null) {
107-
throw new Exception(String.Format("Couldn't find view for '{0}'.", x.ViewModel));
107+
throw new Exception($"Couldn't find view for '{x.ViewModel}'.");
108108
}
109109

110110
view.ViewModel = x.ViewModel;
111111
Content = view;
112112
}));
113-
});
114113

115-
this
116-
.WhenAnyObservable(x => x.ViewContractObservable)
117-
.ObserveOn(RxApp.MainThreadScheduler)
118-
.Subscribe(x => this.viewContract = x);
114+
d(this.WhenAnyObservable(x => x.ViewContractObservable)
115+
.ObserveOn(RxApp.MainThreadScheduler)
116+
.Subscribe(x => viewContract = x));
117+
});
119118
}
120119

121120
static void somethingChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)

0 commit comments

Comments
 (0)