Provide a decent error if unbound generic type used as an abstract factory, and fill in more coverage

This commit is contained in:
Antony Male 2014-05-07 16:22:01 +01:00
parent 6d3a222249
commit fe377e3955
3 changed files with 36 additions and 2 deletions

View File

@ -229,9 +229,9 @@ namespace StyletIoC
public BuilderFactoryBinding(Type serviceType, Func<IContainer, TImplementation> factory) : base(serviceType) public BuilderFactoryBinding(Type serviceType, Func<IContainer, TImplementation> factory) : base(serviceType)
{ {
this.EnsureType(typeof(TImplementation));
if (this.serviceType.IsGenericTypeDefinition) if (this.serviceType.IsGenericTypeDefinition)
throw new StyletIoCRegistrationException(String.Format("A factory cannot be used to implement unbound generic type {0}", this.serviceType.Description())); throw new StyletIoCRegistrationException(String.Format("A factory cannot be used to implement unbound generic type {0}", this.serviceType.Description()));
this.EnsureType(typeof(TImplementation));
this.factory = factory; this.factory = factory;
} }
@ -277,7 +277,11 @@ namespace StyletIoC
internal class AbstractFactoryBinding : BuilderBindingBase internal class AbstractFactoryBinding : BuilderBindingBase
{ {
public AbstractFactoryBinding(Type serviceType) : base(serviceType) { } public AbstractFactoryBinding(Type serviceType) : base(serviceType)
{
if (serviceType.IsGenericTypeDefinition)
throw new StyletIoCRegistrationException(String.Format("Unbound generic type {0} can't be used as an abstract factory", serviceType.Description()));
}
public override void Build(StyletIoCContainer container) public override void Build(StyletIoCContainer container)
{ {

View File

@ -66,5 +66,12 @@ namespace StyletUnitTests
Assert.Throws<StyletIoCRegistrationException>(() => builder.Bind(typeof(I6<>)).To(typeof(C7<,>))); Assert.Throws<StyletIoCRegistrationException>(() => builder.Bind(typeof(I6<>)).To(typeof(C7<,>)));
Assert.Throws<StyletIoCRegistrationException>(() => builder.Bind(typeof(I7<,>)).To(typeof(C6<>))); Assert.Throws<StyletIoCRegistrationException>(() => builder.Bind(typeof(I7<,>)).To(typeof(C6<>)));
} }
[Test]
public void ThrowsIfFactoryBoundToUnboundGeneric()
{
var builder = new StyletIoCBuilder();
Assert.Throws<StyletIoCRegistrationException>(() => builder.Bind(typeof(I6<>)).ToFactory(x => new C6<int>()));
}
} }
} }

View File

@ -53,6 +53,11 @@ namespace StyletUnitTests
void Method(); void Method();
} }
public interface IGenericFactory<T>
{
T GetI1();
}
[Test] [Test]
public void CreatesImplementationWithoutKey() public void CreatesImplementationWithoutKey()
{ {
@ -172,5 +177,23 @@ namespace StyletUnitTests
Assert.Throws<StyletIoCRegistrationException>(() => ioc.Get<I1Factory>()); Assert.Throws<StyletIoCRegistrationException>(() => ioc.Get<I1Factory>());
Assert.NotNull(ioc.Get<I1Factory>("hello")); Assert.NotNull(ioc.Get<I1Factory>("hello"));
} }
[Test]
public void ThrowsIfFactoryTypeIsUnboundGeneric()
{
var builder = new StyletIoCBuilder();
Assert.Throws<StyletIoCRegistrationException>(() => builder.Bind(typeof(IGenericFactory<>)).ToAbstractFactory());
}
[Test]
public void BoundGenericFactoriesWork()
{
var builder = new StyletIoCBuilder();
builder.Bind<I1>().To<C1>();
builder.Bind<IGenericFactory<I1>>().ToAbstractFactory();
var ioc = builder.BuildContainer();
var factory = ioc.Get<IGenericFactory<I1>>();
Assert.IsInstanceOf<C1>(factory.GetI1());
}
} }
} }