From fe377e3955aac1a73e8db015e888bb2a982889e3 Mon Sep 17 00:00:00 2001 From: Antony Male Date: Wed, 7 May 2014 16:22:01 +0100 Subject: [PATCH] Provide a decent error if unbound generic type used as an abstract factory, and fill in more coverage --- Stylet/StyletIoC/StyletIoCBuilder.cs | 8 +++++-- .../StyletIoC/StyletIoCBindingChecksTests.cs | 7 ++++++ .../StyletIoC/StyletIoCFactoryTests.cs | 23 +++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/Stylet/StyletIoC/StyletIoCBuilder.cs b/Stylet/StyletIoC/StyletIoCBuilder.cs index 27fc418..d2b1d45 100644 --- a/Stylet/StyletIoC/StyletIoCBuilder.cs +++ b/Stylet/StyletIoC/StyletIoCBuilder.cs @@ -229,9 +229,9 @@ namespace StyletIoC public BuilderFactoryBinding(Type serviceType, Func factory) : base(serviceType) { - this.EnsureType(typeof(TImplementation)); if (this.serviceType.IsGenericTypeDefinition) 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; } @@ -277,7 +277,11 @@ namespace StyletIoC 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) { diff --git a/StyletUnitTests/StyletIoC/StyletIoCBindingChecksTests.cs b/StyletUnitTests/StyletIoC/StyletIoCBindingChecksTests.cs index e27ffbd..94a2698 100644 --- a/StyletUnitTests/StyletIoC/StyletIoCBindingChecksTests.cs +++ b/StyletUnitTests/StyletIoC/StyletIoCBindingChecksTests.cs @@ -66,5 +66,12 @@ namespace StyletUnitTests Assert.Throws(() => builder.Bind(typeof(I6<>)).To(typeof(C7<,>))); Assert.Throws(() => builder.Bind(typeof(I7<,>)).To(typeof(C6<>))); } + + [Test] + public void ThrowsIfFactoryBoundToUnboundGeneric() + { + var builder = new StyletIoCBuilder(); + Assert.Throws(() => builder.Bind(typeof(I6<>)).ToFactory(x => new C6())); + } } } diff --git a/StyletUnitTests/StyletIoC/StyletIoCFactoryTests.cs b/StyletUnitTests/StyletIoC/StyletIoCFactoryTests.cs index 36dee98..d018dfb 100644 --- a/StyletUnitTests/StyletIoC/StyletIoCFactoryTests.cs +++ b/StyletUnitTests/StyletIoC/StyletIoCFactoryTests.cs @@ -53,6 +53,11 @@ namespace StyletUnitTests void Method(); } + public interface IGenericFactory + { + T GetI1(); + } + [Test] public void CreatesImplementationWithoutKey() { @@ -172,5 +177,23 @@ namespace StyletUnitTests Assert.Throws(() => ioc.Get()); Assert.NotNull(ioc.Get("hello")); } + + [Test] + public void ThrowsIfFactoryTypeIsUnboundGeneric() + { + var builder = new StyletIoCBuilder(); + Assert.Throws(() => builder.Bind(typeof(IGenericFactory<>)).ToAbstractFactory()); + } + + [Test] + public void BoundGenericFactoriesWork() + { + var builder = new StyletIoCBuilder(); + builder.Bind().To(); + builder.Bind>().ToAbstractFactory(); + var ioc = builder.BuildContainer(); + var factory = ioc.Get>(); + Assert.IsInstanceOf(factory.GetI1()); + } } }