diff --git a/src/ReactiveUI.Tests/ViewLocatorTests.cs b/src/ReactiveUI.Tests/ViewLocatorTests.cs index 6dc690c784..47a8827565 100644 --- a/src/ReactiveUI.Tests/ViewLocatorTests.cs +++ b/src/ReactiveUI.Tests/ViewLocatorTests.cs @@ -1,5 +1,4 @@ using System; -using ReactiveUI; using Splat; using Xunit; @@ -72,6 +71,29 @@ object IViewFor.ViewModel public IFooViewModel ViewModel { get; set; } } + public interface StrangeInterfaceNotFollowingConvention { } + + public class StrangeClassNotFollowingConvention : StrangeInterfaceNotFollowingConvention { } + + public interface IRoutableFooViewModel : IRoutableViewModel { } + + public class RoutableFooViewModel : ReactiveObject, IRoutableFooViewModel + { + public IScreen HostScreen { get; set; } + public string UrlPathSegment { get; set; } + } + + public class RoutableFooView : IViewFor + { + object IViewFor.ViewModel + { + get { return ViewModel; } + set { ViewModel = (IRoutableFooViewModel)value; } + } + public IRoutableFooViewModel ViewModel { get; set; } + } + + public class DefaultViewLocatorTests { [Fact] @@ -332,5 +354,40 @@ public void AnErrorIsRaisedIfTheCreationOfTheViewFails() Assert.Equal("This is a test failure.", ex.Message); } } + + [Fact] + public void WithOddInterfaceNameDoesntThrowException() + { + var resolver = new ModernDependencyResolver(); + + resolver.InitializeSplat(); + resolver.InitializeReactiveUI(); + + using (resolver.WithResolver()) { + var fixture = new DefaultViewLocator(); + + var vm = new StrangeClassNotFollowingConvention(); + + fixture.ResolveView((StrangeInterfaceNotFollowingConvention)vm); + } + } + + [Fact] + public void CanResolveViewFromViewModelWithIRoutableViewModelType() + { + var resolver = new ModernDependencyResolver(); + + resolver.InitializeSplat(); + resolver.InitializeReactiveUI(); + resolver.Register(() => new RoutableFooView(), typeof(IViewFor)); + + using (resolver.WithResolver()) { + var fixture = new DefaultViewLocator(); + var vm = new RoutableFooViewModel(); + + var result = fixture.ResolveView(vm); + Assert.IsType(result); + } + } } } diff --git a/src/ReactiveUI/ViewLocator.cs b/src/ReactiveUI/ViewLocator.cs index b92a1621ea..f100daa1fe 100755 --- a/src/ReactiveUI/ViewLocator.cs +++ b/src/ReactiveUI/ViewLocator.cs @@ -77,7 +77,7 @@ public DefaultViewLocator(Func viewModelToViewFunc = null) /// /// /// - /// Repeat steps 1 and 2 with the type resolved from the modified name. + /// Repeat steps 1-4 with the type resolved from the modified name. /// /// /// @@ -107,8 +107,13 @@ public IViewFor ResolveView(T viewModel, string contract = null) return view; } - var toggledType = ToggleViewModelType(viewModel); - view = this.AttemptViewResolutionFor(toggledType, contract); + view = this.AttemptViewResolutionFor(ToggleViewModelType(viewModel.GetType()), contract); + + if (view != null) { + return view; + } + + view = this.AttemptViewResolutionFor(ToggleViewModelType(typeof(T)), contract); if (view != null) { return view; @@ -120,6 +125,7 @@ public IViewFor ResolveView(T viewModel, string contract = null) private IViewFor AttemptViewResolutionFor(Type viewModelType, string contract) { + if (viewModelType == null) return null; var viewModelTypeName = viewModelType.AssemblyQualifiedName; var proposedViewTypeName = this.ViewModelToViewFunc(viewModelTypeName); var view = this.AttemptViewResolution(proposedViewTypeName, contract); @@ -169,9 +175,8 @@ private IViewFor AttemptViewResolution(string viewTypeName, string contract) } } - private static Type ToggleViewModelType(T viewModel) + private static Type ToggleViewModelType(Type viewModelType) { - var viewModelType = typeof(T); var viewModelTypeName = viewModelType.AssemblyQualifiedName; if (viewModelType.GetTypeInfo().IsInterface) {