mirror of https://github.com/AMT-Cheif/Stylet.git
Ensure that FactoryCreators also build up the result
This commit is contained in:
parent
316d9a5e49
commit
fc156247b0
|
@ -17,20 +17,46 @@ namespace StyletIoC
|
|||
internal abstract class CreatorBase : ICreator
|
||||
{
|
||||
public virtual Type Type { get; protected set; }
|
||||
|
||||
protected StyletIoCContainer container;
|
||||
public abstract Expression GetInstanceExpression();
|
||||
|
||||
public CreatorBase(StyletIoCContainer container)
|
||||
{
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
// Common utility method
|
||||
protected Expression CompleteExpressionFromCreator(Expression creator)
|
||||
{
|
||||
var instanceVar = Expression.Variable(this.Type, "instance");
|
||||
var assignment = Expression.Assign(instanceVar, creator);
|
||||
|
||||
var buildUpExpression = this.container.GetBuilderUpper(this.Type).GetExpression(instanceVar);
|
||||
|
||||
// We always start with:
|
||||
// var instance = new Class(.....)
|
||||
// instance.Property1 = new ....
|
||||
// instance.Property2 = new ....
|
||||
var blockItems = new List<Expression>() { assignment, buildUpExpression };
|
||||
// If it implements IInjectionAware, follow that up with:
|
||||
// instance.ParametersInjected
|
||||
if (typeof(IInjectionAware).IsAssignableFrom(this.Type))
|
||||
blockItems.Add(Expression.Call(instanceVar, typeof(IInjectionAware).GetMethod("ParametersInjected")));
|
||||
// Final appearance of instanceVar, as this sets the return value of the block
|
||||
blockItems.Add(instanceVar);
|
||||
var completeExpression = Expression.Block(new[] { instanceVar }, blockItems);
|
||||
return completeExpression;
|
||||
}
|
||||
}
|
||||
|
||||
internal class TypeCreator : CreatorBase
|
||||
{
|
||||
private StyletIoCContainer container;
|
||||
public string AttributeKey { get; private set; }
|
||||
private Expression creationExpression;
|
||||
|
||||
public TypeCreator(Type type, StyletIoCContainer container)
|
||||
public TypeCreator(Type type, StyletIoCContainer container) : base(container)
|
||||
{
|
||||
this.Type = type;
|
||||
this.container = container;
|
||||
|
||||
// Use the key from InjectAttribute (if present), and let someone else override it if they want
|
||||
var attribute = (InjectAttribute)type.GetCustomAttributes(typeof(InjectAttribute), false).FirstOrDefault();
|
||||
|
@ -101,24 +127,9 @@ namespace StyletIoC
|
|||
return Expression.Convert(Expression.Constant(x.DefaultValue), x.ParameterType);
|
||||
});
|
||||
|
||||
var instanceVar = Expression.Variable(this.Type, "instance");
|
||||
var creator = Expression.New(ctor, ctorParams);
|
||||
var assignment = Expression.Assign(instanceVar, creator);
|
||||
|
||||
var buildUpExpression = this.container.GetBuilderUpper(this.Type).GetExpression(instanceVar);
|
||||
|
||||
// We always start with:
|
||||
// var instance = new Class(.....)
|
||||
// instance.Property1 = new ....
|
||||
// instance.Property2 = new ....
|
||||
var blockItems = new List<Expression>() { assignment, buildUpExpression };
|
||||
// If it implements IInjectionAware, follow that up with:
|
||||
// instance.ParametersInjected
|
||||
if (typeof(IInjectionAware).IsAssignableFrom(this.Type))
|
||||
blockItems.Add(Expression.Call(instanceVar, typeof(IInjectionAware).GetMethod("ParametersInjected")));
|
||||
// Final appearance of instanceVar, as this sets the return value of the block
|
||||
blockItems.Add(instanceVar);
|
||||
var completeExpression = Expression.Block(new[] { instanceVar }, blockItems);
|
||||
var completeExpression = this.CompleteExpressionFromCreator(creator);
|
||||
|
||||
this.creationExpression = completeExpression;
|
||||
return completeExpression;
|
||||
|
@ -128,20 +139,27 @@ namespace StyletIoC
|
|||
internal class FactoryCreator<T> : CreatorBase
|
||||
{
|
||||
private Func<StyletIoCContainer, T> factory;
|
||||
private StyletIoCContainer container;
|
||||
private Expression instanceExpression;
|
||||
|
||||
public override Type Type { get { return typeof(T); } }
|
||||
|
||||
public FactoryCreator(Func<StyletIoCContainer, T> factory, StyletIoCContainer container)
|
||||
public FactoryCreator(Func<StyletIoCContainer, T> factory, StyletIoCContainer container) : base(container)
|
||||
{
|
||||
this.factory = factory;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public override Expression GetInstanceExpression()
|
||||
{
|
||||
if (this.instanceExpression != null)
|
||||
return this.instanceExpression;
|
||||
|
||||
var expr = (Expression<Func<T>>)(() => this.factory(this.container));
|
||||
return Expression.Invoke(expr, null);
|
||||
var invoked = Expression.Invoke(expr, null);
|
||||
|
||||
var completeExpression = this.CompleteExpressionFromCreator(invoked);
|
||||
|
||||
this.instanceExpression = completeExpression;
|
||||
return completeExpression;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||
namespace StyletUnitTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class StyletIoCParameterInjectionTests
|
||||
public class StyletIoCPropertyInjectionTests
|
||||
{
|
||||
class C1 { }
|
||||
interface I2 { }
|
||||
|
@ -175,5 +175,18 @@ namespace StyletUnitTests
|
|||
Assert.IsInstanceOf<C1>(subject.C1);
|
||||
Assert.IsTrue(subject.ParametersInjectedCalledCorrectly);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FactoryCreatorBuildsUp()
|
||||
{
|
||||
var builder = new StyletIoCBuilder();
|
||||
builder.Bind<C1>().ToSelf();
|
||||
builder.Bind<Subject1>().ToFactory(c => new Subject1());
|
||||
var ioc = builder.BuildContainer();
|
||||
|
||||
var subject = ioc.Get<Subject1>();
|
||||
|
||||
Assert.IsInstanceOf<C1>(subject.C1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,13 +61,13 @@
|
|||
<Compile Include="PropertyChangedExtensionsTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCAutobindingTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCBindingChecksTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCParameterInjectionTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCPropertyInjectionTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCConstructorInjectionTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCFactoryTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCGetAllTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCGetSingleKeyedTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCGetSingleTests.cs" />
|
||||
<Compile Include="StyletIoC\UnboundGenericTests.cs" />
|
||||
<Compile Include="StyletIoC\StyletIoCUnboundGenericTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
|
||||
|
|
Loading…
Reference in New Issue