Merge branch 'release/1.1.14'

* release/1.1.14:
  Update changelog
  Fix bug in ViewManager when searching multiple assemblies
  Throw (by default) if ToAllImplementations does not find any implementations
  Fix typo in DesignMode sample
  Fix DesignMode sample
This commit is contained in:
Antony Male 2016-03-22 18:42:56 +00:00
commit f8ff7ffa2c
9 changed files with 61 additions and 21 deletions

View File

@ -1,6 +1,14 @@
Stylet Changelog
================
v1.1.14
-------
- Fix bug where ViewManager wouldn't search multiple assemblies for Views
- ViewManager searches the assembly containing the ViewModel by default
- Throw (by default) if StyletIoC's ToAllImplementations() doesn't find any implementations
- Fix typo DesignMode sample
v1.1.13
-------

View File

@ -10,7 +10,7 @@
<DockPanel>
<TextBlock DockPanel.Dock="Top" TextWrapping="Wrap" Margin="10">
This demonstrates "just intellisense" design mode. The Visual Studio XAML designer will show intellisense for bindings
(try and modify the binding below, and see), but does display values from the ViewModel.
(try and modify the binding below, and see), but does not display values from the ViewModel.
</TextBlock>
<TextBlock DockPanel.Dock="Top" Text="{Binding TextBoxText}"/>

View File

@ -123,9 +123,6 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Resource Include="FodyWeavers.xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -69,15 +69,17 @@ namespace StyletIoC
/// Discover all implementations of the service in the specified assemblies / the current assembly, and bind those to the service
/// </summary>
/// <param name="assemblies">Assemblies to search. If empty / null, searches the current assembly</param>
/// <param name="allowZeroImplementations">By default, ToAllImplementations will throw an exception if no implementations are found. Set this parameter to true to allow this case</param>
/// <returns>Fluent interface to continue configuration</returns>
IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(IEnumerable<Assembly> assemblies);
IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(IEnumerable<Assembly> assemblies, bool allowZeroImplementations = false);
/// <summary>
/// Discover all implementations of the service in the specified assemblies / the current assembly, and bind those to the service
/// </summary>
/// <param name="allowZeroImplementations">By default, ToAllImplementations will throw an exception if no implementations are found. Set this parameter to true to allow this case</param>
/// <param name="assemblies">Assemblies to search. If empty / null, searches the current assembly</param>
/// <returns>Fluent interface to continue configuration</returns>
IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(params Assembly[] assemblies);
IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(bool allowZeroImplementations = false, params Assembly[] assemblies);
}
/// <summary>

View File

@ -77,15 +77,15 @@ namespace StyletIoC.Internal.Builders
return this.builderBinding;
}
public IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(IEnumerable<Assembly> assemblies)
public IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(IEnumerable<Assembly> assemblies, bool allowZeroImplementations = false)
{
this.builderBinding = new BuilderToAllImplementationsBinding(this.ServiceTypes, this.getAssemblies(assemblies, "ToAllImplementations"));
this.builderBinding = new BuilderToAllImplementationsBinding(this.ServiceTypes, this.getAssemblies(assemblies, "ToAllImplementations"), allowZeroImplementations);
return this.builderBinding;
}
public IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(params Assembly[] assemblies)
public IInScopeOrWithKeyOrAsWeakBinding ToAllImplementations(bool allowZeroImplementations = false, params Assembly[] assemblies)
{
return this.ToAllImplementations(assemblies.AsEnumerable());
return this.ToAllImplementations(assemblies.AsEnumerable(), allowZeroImplementations);
}
internal void Build(Container container)

View File

@ -10,23 +10,31 @@ namespace StyletIoC.Internal.Builders
internal class BuilderToAllImplementationsBinding : BuilderBindingBase
{
private readonly IEnumerable<Assembly> assemblies;
private readonly bool allowZeroImplementations;
private BuilderTypeKey ServiceType { get { return this.ServiceTypes[0]; } }
public BuilderToAllImplementationsBinding(List<BuilderTypeKey> serviceTypes, IEnumerable<Assembly> assemblies)
public BuilderToAllImplementationsBinding(List<BuilderTypeKey> serviceTypes, IEnumerable<Assembly> assemblies, bool allowZeroImplementations)
: base(serviceTypes)
{
// This should be ensured by the fluent interfaces
Trace.Assert(this.ServiceTypes.Count == 1);
this.assemblies = assemblies;
this.allowZeroImplementations = allowZeroImplementations;
}
public override void Build(Container container)
{
var candidates = from type in this.assemblies.Distinct().SelectMany(x => x.GetTypes())
var candidates = (from type in this.assemblies.Distinct().SelectMany(x => x.GetTypes())
let baseType = type.GetBaseTypesAndInterfaces().FirstOrDefault(x => x == this.ServiceType.Type || (x.IsGenericType && x.GetGenericTypeDefinition() == this.ServiceType.Type))
where baseType != null
select new { Type = type, Base = baseType.ContainsGenericParameters ? baseType.GetGenericTypeDefinition() : baseType };
select new { Type = type, Base = baseType.ContainsGenericParameters ? baseType.GetGenericTypeDefinition() : baseType }).ToList();
if (!this.allowZeroImplementations && candidates.Count == 0)
{
throw new StyletIoCRegistrationException(String.Format("Did not find any implementations of the type {0}", this.ServiceType.Type));
}
foreach (var candidate in candidates)
{

View File

@ -227,13 +227,14 @@ namespace Stylet
}
/// <summary>
/// Given the expected name for a view, locate its type (or throw an exception if a suitable type couldn't be found)
/// Given the expected name for a view, locate its type (or return null if a suitable type couldn't be found)
/// </summary>
/// <param name="viewName">View name to locate the type for</param>
/// <param name="extraAssemblies">Extra assemblies to search through</param>
/// <returns>Type for that view name</returns>
protected virtual Type ViewTypeForViewName(string viewName)
protected virtual Type ViewTypeForViewName(string viewName, IEnumerable<Assembly> extraAssemblies)
{
return this.ViewAssemblies.Select(x => x.GetType(viewName)).FirstOrDefault();
return this.ViewAssemblies.Concat(extraAssemblies).Select(x => x.GetType(viewName)).FirstOrDefault(x => x != null);
}
/// <summary>
@ -277,7 +278,8 @@ namespace Stylet
if (modelName == viewName)
throw new StyletViewLocationException(String.Format("Unable to transform ViewModel name {0} into a suitable View name", modelName), viewName);
var viewType = this.ViewTypeForViewName(viewName);
// Also include the ViewModel's assembly, to be helpful
var viewType = this.ViewTypeForViewName(viewName, new[] { modelType.Assembly });
if (viewType == null)
{
var e = new StyletViewLocationException(String.Format("Unable to find a View with type {0}", viewName), viewName);

View File

@ -26,6 +26,9 @@ namespace StyletUnitTests
[Inject("Key")]
class C4 { }
interface I5 { }
class C5 { }
[Test]
public void NongenericInterfaceToAllImplementations()
{
@ -162,5 +165,24 @@ namespace StyletUnitTests
Assert.IsInstanceOf<C11>(ioc.Get<C11>());
}
[Test]
public void ToAllImplementationsThrowsIfNoImplementationsFound()
{
var builder = new StyletIoCBuilder();
builder.Bind<I5>().ToAllImplementations();
Assert.Throws<StyletIoCRegistrationException>(() => builder.BuildContainer());
}
[Test]
public void ToAllImplementationsDoesNotThrowIfNoImplementationsFoundAndAllowZeroImplementationsIsTrue()
{
var builder = new StyletIoCBuilder();
builder.Bind<I5>().ToAllImplementations(allowZeroImplementations: true);
IContainer ioc = null;
Assert.DoesNotThrow(() => ioc = builder.BuildContainer());
Assert.DoesNotThrow(() => ioc.GetAll<I5>());
}
}
}

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Linq;
namespace StyletUnitTests
{
@ -50,9 +51,9 @@ namespace StyletUnitTests
return base.LocateViewForModel(modelType);
}
public new Type ViewTypeForViewName(string viewName)
public new Type ViewTypeForViewName(string viewName, IEnumerable<Assembly> extraAssemblies)
{
return base.ViewTypeForViewName(viewName);
return base.ViewTypeForViewName(viewName, Enumerable.Empty<Assembly>());
}
}
@ -97,7 +98,7 @@ namespace StyletUnitTests
: base(config) { }
public Type ViewType;
protected override Type ViewTypeForViewName(string viewName)
protected override Type ViewTypeForViewName(string viewName, IEnumerable<Assembly> extraAssemblies)
{
return ViewType;
}
@ -236,7 +237,7 @@ namespace StyletUnitTests
ViewFactory = type => null,
ViewAssemblies = new List<Assembly>() { typeof(BootstrapperBase).Assembly, Assembly.GetExecutingAssembly() }
});
Assert.IsNull(viewManager.ViewTypeForViewName("Test"));
Assert.IsNull(viewManager.ViewTypeForViewName("Test", Enumerable.Empty<Assembly>()));
}
[Test]