Skip to content

Commit

Permalink
StructureMap service resolution is completely working in the code gen…
Browse files Browse the repository at this point in the history
…eration
  • Loading branch information
jeremydmiller committed Dec 18, 2016
1 parent 6a16b2c commit 47eb36c
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 76 deletions.
35 changes: 21 additions & 14 deletions src/Jasper.Testing/Codegen/CompilationContext.cs
Expand Up @@ -18,52 +18,59 @@ public class CompilationContext
private static int _number = 0;
public readonly HandlerChain theChain;
public readonly ServiceRegistry services = new ServiceRegistry();
private string _code = null;

public CompilationContext()
{
theChain = new HandlerChain($"Handler{++_number}",
typeof(IInputHandler));


_container = new Lazy<IContainer>(() => new Container(services));
}

protected string theGeneratedCode
{
get
{
var config = new GenerationConfig("Jasper.Testing.Codegen.Generated");
var container = new Container(services);
config.Sources.Add(new StructureMapServices(container));

config.Assemblies.Add(GetType().GetTypeInfo().Assembly);

var @set = new HandlerSet<MainInput, HandlerChain>(config, "input");
if (_code == null)
{
var set = buildHandlerSet();

@set.Add(theChain);
_code = @set.GenerateCode();
}

return @set.GenerateCode();
return _code;
}
}

private IInputHandler generate()
private Lazy<IContainer> _container;

private HandlerSet<MainInput, HandlerChain> buildHandlerSet()
{
var config = new GenerationConfig("Jasper.Testing.Codegen.Generated");

var container = new Container(services);
var container = _container.Value;
config.Sources.Add(new StructureMapServices(container));

config.Assemblies.Add(typeof(IContainer).GetTypeInfo().Assembly);
config.Assemblies.Add(GetType().GetTypeInfo().Assembly);

var @set = new HandlerSet<MainInput, HandlerChain>(config, "input");

@set.Add(theChain);

return set;
}

private IInputHandler generate()
{
var @set = buildHandlerSet();

var code = @set.GenerateCode();
Console.WriteLine(code);

var type = @set.CompileAll().Single();

return container.GetInstance(type).As<IInputHandler>();
return _container.Value.GetInstance(type).As<IInputHandler>();
}

protected Task<MainInput> afterRunning()
Expand Down
2 changes: 1 addition & 1 deletion src/Jasper.Testing/Codegen/InjectedFieldTests.cs
@@ -1,5 +1,5 @@
using Jasper.Codegen;
using Jasper.Testing.Codegen.StructureMap;
using Jasper.Testing.Codegen.IoC;
using Shouldly;
using Xunit;

Expand Down
Expand Up @@ -5,7 +5,7 @@
using StructureMap;
using Xunit;

namespace Jasper.Testing.Codegen.StructureMap
namespace Jasper.Testing.Codegen.IoC
{
public class StructureMapServicesTests
{
Expand Down
@@ -1,9 +1,7 @@
using System;
using System.Threading.Tasks;
using StructureMap;
using System.Threading.Tasks;
using Xunit;

namespace Jasper.Testing.Codegen.StructureMap
namespace Jasper.Testing.Codegen.IoC
{
public class end_to_end_structuremap_usage : CompilationContext
{
Expand Down Expand Up @@ -34,9 +32,9 @@ public async Task use_variable_created_from_nested_container()
theChain.Call<ITouchService>(x => x.Touch(null));

theGeneratedCode
.ShouldContain($"using (var nested = root.GetNestedContainer())");
.ShouldContain($"using (var nested = _root.GetNestedContainer())");

theGeneratedCode.ShouldContain("var touchService = nested.GetInstance<Jasper.Testing.Codegen.StructureMap.ITouchService>();");
theGeneratedCode.ShouldContain("var touchService = nested.GetInstance<Jasper.Testing.Codegen.IoC.ITouchService>();");

var input = await afterRunning();

Expand Down
19 changes: 17 additions & 2 deletions src/Jasper/Codegen/Frame.cs
@@ -1,4 +1,5 @@
using Jasper.Codegen.Compilation;
using System.Linq;
using Jasper.Codegen.Compilation;
using Jasper.Configuration;

namespace Jasper.Codegen
Expand All @@ -12,7 +13,19 @@ protected Frame(bool isAsync)
IsAsync = isAsync;
}

public abstract void GenerateCode(HandlerGeneration generation, ISourceWriter writer);
public void GenerateCode(HandlerGeneration generation, ISourceWriter writer)
{
if (Instantiates.Any())
{
Instantiates[0].GenerateCreationCode(generation, this, writer);
}
else
{
generateCode(generation, writer);
}
}

internal abstract void generateCode(HandlerGeneration generation, ISourceWriter writer);

// Going to say that other policies will deal w/ the existence of wrappers
// Go find necessary variables, add any necessary wrappers
Expand All @@ -26,5 +39,7 @@ public virtual void ResolveVariables(HandlerGeneration chain)
// Use a visitor to find that?

public virtual bool CanReturnTask() => false;

public Variable[] Instantiates { get; set; } = new Variable[0];
}
}
11 changes: 5 additions & 6 deletions src/Jasper/Codegen/HandlerGeneration.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Baseline;

namespace Jasper.Codegen
{
Expand Down Expand Up @@ -83,13 +84,11 @@ private void resolveVariables(Frame frame)
frame.ResolveVariables(this);

var ordered = GatherAllDependencies(_variables.Values.ToArray())
.Where(x => x.Creation == VariableCreation.BuiltByFrame && !_created.Contains(x));
.Where(x => x.Creation == VariableCreation.BuiltByFrame && !_created.Contains(x))
.ToArray();

foreach (var variable in ordered)
{
_created.Add(variable);
variable.AttachFrame(frame);
}
_created.AddRange(ordered);
frame.Instantiates = ordered;
}
}
}
4 changes: 2 additions & 2 deletions src/Jasper/Codegen/MethodCall.cs
Expand Up @@ -44,7 +44,7 @@ public override void ResolveVariables(HandlerGeneration chain)
}
}

public override void GenerateCode(HandlerGeneration generation, ISourceWriter writer)
internal override void generateCode(HandlerGeneration generation, ISourceWriter writer)
{
var callingCode = $"{_method.Name}({_variables.Select(x => x.Name).Join(", ")})";
var target = _method.IsStatic
Expand Down Expand Up @@ -73,9 +73,9 @@ public override void GenerateCode(HandlerGeneration generation, ISourceWriter wr
writer.Write($"{returnValue}{target}.{callingCode}{suffix};");

Next?.GenerateCode(generation, writer);

}


public override bool CanReturnTask()
{
return IsAsync;
Expand Down
40 changes: 6 additions & 34 deletions src/Jasper/Codegen/StructureMap/StructureMapServices.cs
Expand Up @@ -67,30 +67,17 @@ public override IEnumerable<Variable> Dependencies
}
}

protected override Frame toInstantiationFrame()
{
return new ResolveFromNestedContainer(this);
}
}

public class ResolveFromNestedContainer : Frame
{
private readonly Variable _variable;

public ResolveFromNestedContainer(Variable variable) : base(false)
protected override void generateCreation(ISourceWriter writer, Action<ISourceWriter> continuation)
{
_variable = variable;
}

public override void GenerateCode(HandlerGeneration generation, ISourceWriter writer)
{
writer.Write($"var {_variable.Name} = {StructureMapServices.Nested.Name}.GetInstance<{_variable.VariableType.FullName}>();");
Next?.GenerateCode(generation, writer);
writer.Write($"var {Name} = {StructureMapServices.Nested.Name}.GetInstance<{VariableType.FullName}>();");
continuation(writer);
}
}




public class NestedContainerVariable : Variable
{
public NestedContainerVariable() : base(typeof(IContainer), "nested", VariableCreation.BuiltByFrame)
Expand All @@ -102,24 +89,9 @@ public override IEnumerable<Variable> Dependencies
get { yield return StructureMapServices.Root; }
}

protected override Frame toInstantiationFrame()
protected override void generateCreation(ISourceWriter writer, Action<ISourceWriter> continuation)
{
return new NestedContainerCreation();
}
}

public class NestedContainerCreation : Frame
{
public NestedContainerCreation() : base(false)
{
}

public override void GenerateCode(HandlerGeneration generation, ISourceWriter writer)
{
writer.UsingBlock("var nested = root.GetNestedContainer()", w =>
{
Next?.GenerateCode(generation, writer);
});
writer.UsingBlock("var nested = _root.GetNestedContainer()", continuation);
}
}

Expand Down
26 changes: 16 additions & 10 deletions src/Jasper/Codegen/Variable.cs
Expand Up @@ -3,6 +3,7 @@
using System.Linq;
using System.Reflection;
using Baseline;
using Jasper.Codegen.Compilation;
using Jasper.Util;

namespace Jasper.Codegen
Expand Down Expand Up @@ -32,8 +33,6 @@ private void gather(List<Variable> list)
}
}

// TODO -- change this. Too ugly. Strip out the initial "I" if an interface
// Use camel casing instead
public static string DefaultArgName(Type argType)
{
var parts = argType.Name.SplitPascalCase().Split(' ');
Expand Down Expand Up @@ -61,12 +60,6 @@ public Variable(Type argType, string name, VariableCreation creation)
public VariableCreation Creation { get; }
public Type VariableType { get; }

internal void AttachFrame(Frame frameUsingVariable)
{
var frame = toInstantiationFrame();
frameUsingVariable.AddBefore(frame);
}

public virtual IEnumerable<Variable> Dependencies
{
get
Expand All @@ -75,10 +68,23 @@ public virtual IEnumerable<Variable> Dependencies
}
}

protected virtual Frame toInstantiationFrame()

public void GenerateCreationCode(HandlerGeneration generation, Frame frame, ISourceWriter writer)
{
return null;
if (ReferenceEquals(this, frame.Instantiates.Last()))
{
generateCreation(writer, w => frame.generateCode(generation, writer));
return;
}

var index = Array.IndexOf(frame.Instantiates, this);
var next = frame.Instantiates[index + 1];
generateCreation(writer, w => next.GenerateCreationCode(generation, frame, writer));
}

protected virtual void generateCreation(ISourceWriter writer, Action<ISourceWriter> continuation)
{
throw new NotSupportedException("This feature has to be implemented for this type of Variable");
}
}
}

0 comments on commit 47eb36c

Please sign in to comment.