|
From: <jer...@us...> - 2007-03-26 01:52:42
|
Revision: 29
http://structuremap.svn.sourceforge.net/structuremap/?rev=29&view=rev
Author: jeremydmiller
Date: 2007-03-25 18:52:39 -0700 (Sun, 25 Mar 2007)
Log Message:
-----------
Adding some defensive programming to the Fluent Interface API
Modified Paths:
--------------
trunk/Source/StructureMap/Configuration/DSL/ChildInstanceExpression.cs
trunk/Source/StructureMap/Configuration/DSL/CreatePluginFamilyExpression.cs
trunk/Source/StructureMap/Configuration/DSL/IMementoBuilder.cs
trunk/Source/StructureMap/Configuration/DSL/InstanceDefaultExpression.cs
trunk/Source/StructureMap/Configuration/DSL/InstanceExpression.cs
trunk/Source/StructureMap/Configuration/DSL/LiteralExpression.cs
trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs
trunk/Source/StructureMap/Configuration/DSL/PrototypeExpression.cs
trunk/Source/StructureMap/Graph/Plugin.cs
trunk/Source/StructureMap/StructureMapException.resx
trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs
trunk/Source/StructureMap.Testing/Configuration/DSL/InstanceExpressionTester.cs
Added Paths:
-----------
trunk/Source/StructureMap/Configuration/DSL/ExpressionValidator.cs
trunk/Source/StructureMap.Testing/Configuration/DSL/ChildInstanceExpressionTester.cs
Modified: trunk/Source/StructureMap/Configuration/DSL/ChildInstanceExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/ChildInstanceExpression.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/ChildInstanceExpression.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -21,7 +21,13 @@
_propertyName = propertyName;
}
+ public ChildInstanceExpression(InstanceExpression instance, MemoryInstanceMemento memento, string propertyName, Type childType)
+ : this(instance, memento, propertyName)
+ {
+ _childType = childType;
+ }
+
public InstanceExpression IsNamedInstance(string instanceKey)
{
MemoryInstanceMemento child = MemoryInstanceMemento.CreateReferencedInstanceMemento(instanceKey);
@@ -30,9 +36,11 @@
return _instance;
}
- // TODO -- negative case if the concrete type cannot be an implicit instance
public InstanceExpression IsConcreteType<T>()
{
+ Type pluggedType = typeof (T);
+ ExpressionValidator.ValidatePluggabilityOf(pluggedType).IntoPluginType(_childType);
+
InstanceExpression child = new InstanceExpression(_childType);
child.UsingConcreteType<T>();
_children.Add(child);
@@ -70,6 +78,11 @@
public InstanceExpression Is(InstanceExpression child)
{
+ if (child.PluggedType != null && _childType != null)
+ {
+ ExpressionValidator.ValidatePluggabilityOf(child.PluggedType).IntoPluginType(_childType);
+ }
+
_children.Add(child);
MemoryInstanceMemento childMemento =
MemoryInstanceMemento.CreateReferencedInstanceMemento(child.InstanceKey);
Modified: trunk/Source/StructureMap/Configuration/DSL/CreatePluginFamilyExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/CreatePluginFamilyExpression.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/CreatePluginFamilyExpression.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -19,7 +19,7 @@
_pluginType = pluginType;
}
- public void Configure(PluginGraph graph)
+ void IExpression.Configure(PluginGraph graph)
{
PluginFamily family = graph.LocateOrCreateFamilyForType(_pluginType);
InterceptorChainBuilder builder = new InterceptorChainBuilder();
@@ -36,26 +36,10 @@
graph.Assemblies.Add(assembly);
}
- public CreatePluginFamilyExpression WithDefaultConcreteType<T>()
- {
- Plugin plugin = addPlugin<T>();
-
- _alterations.Add(delegate(PluginFamily family) { family.DefaultInstanceKey = plugin.ConcreteKey; });
-
- return this;
- }
-
- private Plugin addPlugin<T>()
- {
- Plugin plugin = Plugin.CreateImplicitPlugin(typeof (T));
-
- _alterations.Add(delegate(PluginFamily family) { family.Plugins.Add(plugin); });
-
- return plugin;
- }
-
public CreatePluginFamilyExpression TheDefaultIs(IMementoBuilder builder)
{
+ builder.ValidatePluggability(_pluginType);
+
_alterations.Add(delegate(PluginFamily family)
{
InstanceMemento memento = builder.BuildMemento(family);
@@ -68,6 +52,8 @@
public CreatePluginFamilyExpression TheDefaultIsConcreteType<T>()
{
+ ExpressionValidator.ValidatePluggabilityOf(typeof(T)).IntoPluginType(_pluginType);
+
_alterations.Add(delegate(PluginFamily family)
{
Plugin plugin = family.Plugins.FindOrCreate(typeof (T));
Added: trunk/Source/StructureMap/Configuration/DSL/ExpressionValidator.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/ExpressionValidator.cs (rev 0)
+++ trunk/Source/StructureMap/Configuration/DSL/ExpressionValidator.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -0,0 +1,35 @@
+using System;
+using StructureMap.Graph;
+
+namespace StructureMap.Configuration.DSL
+{
+ public static class ExpressionValidator
+ {
+ public static ValidateExpression ValidatePluggabilityOf(Type pluggedType)
+ {
+ return new ValidateExpression(pluggedType);
+ }
+
+
+ public class ValidateExpression
+ {
+ private readonly Type _pluggedType;
+
+ public ValidateExpression(Type pluggedType)
+ {
+ _pluggedType = pluggedType;
+ }
+
+ public void IntoPluginType(Type pluginType)
+ {
+ if (!Plugin.CanBeCast(pluginType, _pluggedType))
+ {
+ throw new StructureMapException(
+ 303,
+ TypePath.GetAssemblyQualifiedName(_pluggedType),
+ TypePath.GetAssemblyQualifiedName(pluginType));
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Configuration/DSL/IMementoBuilder.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/IMementoBuilder.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/IMementoBuilder.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -1,3 +1,4 @@
+using System;
using StructureMap.Graph;
namespace StructureMap.Configuration.DSL
@@ -7,5 +8,7 @@
InstanceMemento BuildMemento(PluginFamily family);
InstanceMemento BuildMemento(PluginGraph graph);
void SetInstanceName(string instanceKey);
+
+ void ValidatePluggability(Type pluginType);
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Configuration/DSL/InstanceDefaultExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/InstanceDefaultExpression.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/InstanceDefaultExpression.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -22,7 +22,7 @@
return _parent;
}
- public void Configure(Profile profile, PluginGraph graph)
+ internal void Configure(Profile profile, PluginGraph graph)
{
if (!string.IsNullOrEmpty(_instanceKey))
{
@@ -40,8 +40,10 @@
InstanceDefault instanceDefault = new InstanceDefault(_pluginType, defaultKey);
profile.AddOverride(instanceDefault);
}
-
- // TODO throw up!!!
+ else
+ {
+ throw new StructureMapException(304, TypePath.GetAssemblyQualifiedName(_pluginType));
+ }
}
public ProfileExpression Use(IMementoBuilder mementoBuilder)
Modified: trunk/Source/StructureMap/Configuration/DSL/InstanceExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/InstanceExpression.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/InstanceExpression.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -12,6 +12,12 @@
{
}
+
+ internal Type PluggedType
+ {
+ get { return _pluggedType; }
+ }
+
protected override void buildMemento()
{
_memento = new MemoryInstanceMemento();
@@ -75,8 +81,13 @@
public ChildInstanceExpression Child<T>()
{
- // TODO -- what if the property can't be found
string propertyName = findPropertyName<T>();
+
+ if (string.IsNullOrEmpty(propertyName))
+ {
+ throw new StructureMapException(305, TypePath.GetAssemblyQualifiedName(typeof (T)));
+ }
+
ChildInstanceExpression child = new ChildInstanceExpression(this, _memento, propertyName);
addChildExpression(child);
child.ChildType = typeof (T);
@@ -88,5 +99,15 @@
Plugin plugin = Plugin.CreateImplicitPlugin(_pluggedType);
return plugin.FindFirstConstructorArgumentOfType<T>();
}
+
+ public override void ValidatePluggability(Type pluginType)
+ {
+ if (_pluggedType == null)
+ {
+ return;
+ }
+
+ ExpressionValidator.ValidatePluggabilityOf(_pluggedType).IntoPluginType(pluginType);
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Configuration/DSL/LiteralExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/LiteralExpression.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/LiteralExpression.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -1,3 +1,4 @@
+using System;
using StructureMap.Graph;
namespace StructureMap.Configuration.DSL
@@ -36,5 +37,10 @@
{
_memento = new LiteralMemento(null);
}
+
+ public override void ValidatePluggability(Type pluginType)
+ {
+ ExpressionValidator.ValidatePluggabilityOf(_target.GetType()).IntoPluginType(pluginType);
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/MementoBuilder.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -88,6 +88,8 @@
_instanceKey = instanceKey;
}
+ public abstract void ValidatePluggability(Type pluginType);
+
protected void addChildExpression(IExpression expression)
{
_children.Add(expression);
Modified: trunk/Source/StructureMap/Configuration/DSL/PrototypeExpression.cs
===================================================================
--- trunk/Source/StructureMap/Configuration/DSL/PrototypeExpression.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Configuration/DSL/PrototypeExpression.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -37,5 +37,10 @@
{
_memento = new PrototypeMemento(string.Empty, (ICloneable) _prototype);
}
+
+ public override void ValidatePluggability(Type pluginType)
+ {
+ ExpressionValidator.ValidatePluggabilityOf(_prototype.GetType()).IntoPluginType(pluginType);
+ }
}
}
\ No newline at end of file
Modified: trunk/Source/StructureMap/Graph/Plugin.cs
===================================================================
--- trunk/Source/StructureMap/Graph/Plugin.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/Graph/Plugin.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -82,6 +82,11 @@
/// <returns></returns>
public static bool CanBeCast(Type pluginType, Type pluggedType)
{
+ if (pluggedType.IsInterface || pluggedType.IsAbstract)
+ {
+ return false;
+ }
+
if (GenericsPluginGraph.CanBeCast(pluginType, pluggedType))
{
return true;
Modified: trunk/Source/StructureMap/StructureMapException.resx
===================================================================
--- trunk/Source/StructureMap/StructureMapException.resx 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap/StructureMapException.resx 2007-03-26 01:52:39 UTC (rev 29)
@@ -237,4 +237,13 @@
<data name="302" xml:space="preserve">
<value>There is no argument of type {0} for concrete type {1}</value>
</data>
+ <data name="303" xml:space="preserve">
+ <value>Type {0} is either abstract or cannot be plugged into Type {1}</value>
+ </data>
+ <data name="304" xml:space="preserve">
+ <value>Profile or Machine default for {0} not completely specified</value>
+ </data>
+ <data name="305" xml:space="preserve">
+ <value>There is no constructor property found of type {0}</value>
+ </data>
</root>
\ No newline at end of file
Added: trunk/Source/StructureMap.Testing/Configuration/DSL/ChildInstanceExpressionTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Configuration/DSL/ChildInstanceExpressionTester.cs (rev 0)
+++ trunk/Source/StructureMap.Testing/Configuration/DSL/ChildInstanceExpressionTester.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -0,0 +1,60 @@
+using NUnit.Framework;
+using StructureMap.Configuration.DSL;
+using StructureMap.Testing.Widget4;
+
+namespace StructureMap.Testing.Configuration.DSL
+{
+ [TestFixture]
+ public class ChildInstanceExpressionTester
+ {
+ [SetUp]
+ public void SetUp()
+ {
+ }
+
+ [Test, ExpectedException(typeof(StructureMapException), "StructureMap Exception Code: 303\nType System.String,mscorlib is either abstract or cannot be plugged into Type StructureMap.Testing.Configuration.DSL.IType,StructureMap.Testing")]
+ public void CantCastTheRequestedConcreteType()
+ {
+ InstanceExpression instance = new InstanceExpression(typeof(IStrategy));
+ MemoryInstanceMemento memento = new MemoryInstanceMemento();
+
+ ChildInstanceExpression expression = new ChildInstanceExpression(instance, memento, "a property", typeof(IType));
+ expression.IsConcreteType<string>();
+ }
+
+ [Test, ExpectedException(typeof(StructureMapException), "StructureMap Exception Code: 303\nType StructureMap.Testing.Configuration.DSL.AbstractType,StructureMap.Testing is either abstract or cannot be plugged into Type StructureMap.Testing.Configuration.DSL.IType,StructureMap.Testing")]
+ public void CantCastTheRequestedConcreteType2()
+ {
+ InstanceExpression instance = new InstanceExpression(typeof(IStrategy));
+ MemoryInstanceMemento memento = new MemoryInstanceMemento();
+
+ ChildInstanceExpression expression = new ChildInstanceExpression(instance, memento, "a property", typeof(IType));
+ expression.IsConcreteType<AbstractType>();
+ }
+
+
+ [Test, ExpectedException(typeof(StructureMapException), "StructureMap Exception Code: 303\nType StructureMap.Testing.Configuration.DSL.AbstractType,StructureMap.Testing is either abstract or cannot be plugged into Type StructureMap.Testing.Configuration.DSL.IType,StructureMap.Testing")]
+ public void CantCastTheRequestedPluggedType3()
+ {
+ InstanceExpression instance = new InstanceExpression(typeof(IStrategy));
+ MemoryInstanceMemento memento = new MemoryInstanceMemento();
+
+ ChildInstanceExpression expression = new ChildInstanceExpression(instance, memento, "a property", typeof(IType));
+ InstanceExpression child = new InstanceExpression(typeof(IType)).UsingConcreteType<AbstractType>();
+ expression.Is(child);
+ }
+ }
+
+ public interface IType
+ {
+ }
+
+ public abstract class AbstractType : IType
+ {
+ }
+
+ public class ConcreteType : AbstractType
+ {
+
+ }
+}
\ No newline at end of file
Modified: trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap.Testing/Configuration/DSL/CreatePluginFamilyTester.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -17,6 +17,13 @@
}
+ [Test, ExpectedException(typeof(StructureMapException))]
+ public void TheConceteTypeDoesNotCase()
+ {
+ Registry registry = new Registry();
+ registry.BuildInstancesOf<Rule>().TheDefaultIsConcreteType<IWidget>();
+ }
+
[Test]
public void TheDefaultInstanceIsConcreteType()
{
@@ -66,7 +73,7 @@
using (Registry registry = new Registry(pluginGraph))
{
// Specify the default implementation for an interface
- registry.BuildInstancesOf<IGateway>().WithDefaultConcreteType<StubbedGateway>();
+ registry.BuildInstancesOf<IGateway>().TheDefaultIsConcreteType<StubbedGateway>();
}
Assert.IsTrue(pluginGraph.PluginFamilies.Contains<IGateway>());
@@ -142,7 +149,7 @@
PluginGraph pluginGraph = new PluginGraph();
using (Registry registry = new Registry(pluginGraph))
{
- registry.BuildInstancesOf<IGateway>().WithDefaultConcreteType<FakeGateway>();
+ registry.BuildInstancesOf<IGateway>().TheDefaultIsConcreteType<FakeGateway>();
}
Assert.IsTrue(pluginGraph.PluginFamilies.Contains<IGateway>());
Modified: trunk/Source/StructureMap.Testing/Configuration/DSL/InstanceExpressionTester.cs
===================================================================
--- trunk/Source/StructureMap.Testing/Configuration/DSL/InstanceExpressionTester.cs 2007-03-25 02:56:13 UTC (rev 28)
+++ trunk/Source/StructureMap.Testing/Configuration/DSL/InstanceExpressionTester.cs 2007-03-26 01:52:39 UTC (rev 29)
@@ -21,5 +21,13 @@
PluginGraph pluginGraph = new PluginGraph();
((IExpression)expression).Configure(pluginGraph);
}
+
+ [Test, ExpectedException(typeof(StructureMapException))]
+ public void BlowUpIfNoPropertyIsFoundForType()
+ {
+ InstanceExpression expression = new InstanceExpression(typeof(IWidget));
+ expression.UsingConcreteType<AWidget>();
+ expression.Child<Rule>();
+ }
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|