Implemented #10: YieldWithParallelRequest
This commit is contained in:
parent
6b2a562d62
commit
120108bd41
@ -3,15 +3,7 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace Tapeti.Flow.Default
|
namespace Tapeti.Flow.Default
|
||||||
{
|
{
|
||||||
internal interface IExecutableYieldPoint : IYieldPoint
|
internal class DelegateYieldPoint : IStateYieldPoint, IExecutableYieldPoint
|
||||||
{
|
|
||||||
bool StoreState { get; }
|
|
||||||
|
|
||||||
Task Execute(FlowContext context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
internal class DelegateYieldPoint : IYieldPoint
|
|
||||||
{
|
{
|
||||||
public bool StoreState { get; }
|
public bool StoreState { get; }
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ namespace Tapeti.Flow.Default
|
|||||||
{
|
{
|
||||||
public void Handle(IBindingContext context, Action next)
|
public void Handle(IBindingContext context, Action next)
|
||||||
{
|
{
|
||||||
RegisterContinuationFilter(context);
|
|
||||||
RegisterYieldPointResult(context);
|
RegisterYieldPointResult(context);
|
||||||
|
RegisterContinuationFilter(context);
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
|
||||||
@ -29,6 +29,26 @@ namespace Tapeti.Flow.Default
|
|||||||
|
|
||||||
context.Use(new FlowMessageFilterMiddleware());
|
context.Use(new FlowMessageFilterMiddleware());
|
||||||
context.Use(new FlowMessageMiddleware());
|
context.Use(new FlowMessageMiddleware());
|
||||||
|
|
||||||
|
if (context.Result.HasHandler)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Continuation without IYieldPoint indicates a ParallelRequestBuilder response handler,
|
||||||
|
// make sure to store it's state as well
|
||||||
|
if (context.Result.Info.ParameterType == typeof(Task))
|
||||||
|
{
|
||||||
|
context.Result.SetHandler(async (messageContext, value) =>
|
||||||
|
{
|
||||||
|
await (Task)value;
|
||||||
|
await HandleParallelResponse(messageContext);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (context.Result.Info.ParameterType == typeof(void))
|
||||||
|
{
|
||||||
|
context.Result.SetHandler((messageContext, value) => HandleParallelResponse(messageContext));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new ArgumentException($"Result type must be IYieldPoint, Task or void in controller {context. Method.DeclaringType?.FullName}, method {context.Method.Name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -59,6 +79,13 @@ namespace Tapeti.Flow.Default
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Task HandleParallelResponse(IMessageContext context)
|
||||||
|
{
|
||||||
|
var flowHandler = context.DependencyResolver.Resolve<IFlowHandler>();
|
||||||
|
return flowHandler.Execute(context, new StateYieldPoint(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void ValidateRequestResponse(IBindingContext context)
|
private static void ValidateRequestResponse(IBindingContext context)
|
||||||
{
|
{
|
||||||
var request = context.MessageClass?.GetCustomAttribute<RequestAttribute>();
|
var request = context.MessageClass?.GetCustomAttribute<RequestAttribute>();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Tapeti.Config;
|
using Tapeti.Config;
|
||||||
|
|
||||||
@ -13,12 +14,41 @@ namespace Tapeti.Flow.Default
|
|||||||
{
|
{
|
||||||
Newtonsoft.Json.JsonConvert.PopulateObject(flowContext.FlowState.Data, context.Controller);
|
Newtonsoft.Json.JsonConvert.PopulateObject(flowContext.FlowState.Data, context.Controller);
|
||||||
|
|
||||||
|
// Remove Continuation now because the IYieldPoint result handler will store the new state
|
||||||
|
flowContext.FlowState.Continuations.Remove(flowContext.ContinuationID);
|
||||||
|
var converge = flowContext.FlowState.Continuations.Count == 0 &&
|
||||||
|
flowContext.ContinuationMetadata.ConvergeMethodName != null;
|
||||||
|
|
||||||
await next();
|
await next();
|
||||||
|
|
||||||
flowContext.FlowState.Continuations.Remove(flowContext.ContinuationID);
|
if (converge)
|
||||||
|
await CallConvergeMethod(context,
|
||||||
|
flowContext.ContinuationMetadata.ConvergeMethodName,
|
||||||
|
flowContext.ContinuationMetadata.ConvergeMethodSync);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static async Task CallConvergeMethod(IMessageContext context, string methodName, bool sync)
|
||||||
|
{
|
||||||
|
IYieldPoint yieldPoint;
|
||||||
|
|
||||||
|
var method = context.Controller.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
|
||||||
|
if (method == null)
|
||||||
|
throw new ArgumentException($"Unknown converge method in controller {context.Controller.GetType().Name}: {methodName}");
|
||||||
|
|
||||||
|
if (sync)
|
||||||
|
yieldPoint = (IYieldPoint)method.Invoke(context.Controller, new object[] {});
|
||||||
|
else
|
||||||
|
yieldPoint = await (Task<IYieldPoint>)method.Invoke(context.Controller, new object[] { });
|
||||||
|
|
||||||
|
if (yieldPoint == null)
|
||||||
|
throw new YieldPointException($"Yield point is required in controller {context.Controller.GetType().Name} for converge method {methodName}");
|
||||||
|
|
||||||
|
var flowHandler = context.DependencyResolver.Resolve<IFlowHandler>();
|
||||||
|
await flowHandler.Execute(context, yieldPoint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using RabbitMQ.Client.Framing;
|
using RabbitMQ.Client.Framing;
|
||||||
@ -36,8 +37,7 @@ namespace Tapeti.Flow.Default
|
|||||||
|
|
||||||
public IFlowParallelRequestBuilder YieldWithParallelRequest()
|
public IFlowParallelRequestBuilder YieldWithParallelRequest()
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
return new ParallelRequestBuilder(config, SendRequest);
|
||||||
//return new ParallelRequestBuilder();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IYieldPoint EndWithResponse<TResponse>(TResponse message)
|
public IYieldPoint EndWithResponse<TResponse>(TResponse message)
|
||||||
@ -51,7 +51,8 @@ namespace Tapeti.Flow.Default
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task SendRequest(FlowContext context, object message, ResponseHandlerInfo responseHandlerInfo)
|
private async Task SendRequest(FlowContext context, object message, ResponseHandlerInfo responseHandlerInfo,
|
||||||
|
string convergeMethodName = null, bool convergeMethodTaskSync = false)
|
||||||
{
|
{
|
||||||
var continuationID = Guid.NewGuid();
|
var continuationID = Guid.NewGuid();
|
||||||
|
|
||||||
@ -59,7 +60,8 @@ namespace Tapeti.Flow.Default
|
|||||||
new ContinuationMetadata
|
new ContinuationMetadata
|
||||||
{
|
{
|
||||||
MethodName = responseHandlerInfo.MethodName,
|
MethodName = responseHandlerInfo.MethodName,
|
||||||
ConvergeMethodName = null
|
ConvergeMethodName = convergeMethodName,
|
||||||
|
ConvergeMethodSync = convergeMethodTaskSync
|
||||||
});
|
});
|
||||||
|
|
||||||
var properties = new BasicProperties
|
var properties = new BasicProperties
|
||||||
@ -144,8 +146,10 @@ namespace Tapeti.Flow.Default
|
|||||||
|
|
||||||
public async Task Execute(IMessageContext context, IYieldPoint yieldPoint)
|
public async Task Execute(IMessageContext context, IYieldPoint yieldPoint)
|
||||||
{
|
{
|
||||||
var delegateYieldPoint = (DelegateYieldPoint)yieldPoint;
|
var stateYieldPoint = yieldPoint as IStateYieldPoint;
|
||||||
var storeState = delegateYieldPoint.StoreState;
|
var executableYieldPoint = yieldPoint as IExecutableYieldPoint;
|
||||||
|
|
||||||
|
var storeState = stateYieldPoint?.StoreState ?? false;
|
||||||
|
|
||||||
FlowContext flowContext;
|
FlowContext flowContext;
|
||||||
object flowContextItem;
|
object flowContextItem;
|
||||||
@ -181,7 +185,8 @@ namespace Tapeti.Flow.Default
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await delegateYieldPoint.Execute(flowContext);
|
if (executableYieldPoint != null)
|
||||||
|
await executableYieldPoint.Execute(flowContext);
|
||||||
}
|
}
|
||||||
catch (YieldPointException e)
|
catch (YieldPointException e)
|
||||||
{
|
{
|
||||||
@ -203,10 +208,16 @@ namespace Tapeti.Flow.Default
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
private class ParallelRequestBuilder : IFlowParallelRequestBuilder
|
private class ParallelRequestBuilder : IFlowParallelRequestBuilder
|
||||||
{
|
{
|
||||||
internal class RequestInfo
|
public delegate Task SendRequestFunc(FlowContext context,
|
||||||
|
object message,
|
||||||
|
ResponseHandlerInfo responseHandlerInfo,
|
||||||
|
string convergeMethodName,
|
||||||
|
bool convergeMethodSync);
|
||||||
|
|
||||||
|
|
||||||
|
private class RequestInfo
|
||||||
{
|
{
|
||||||
public object Message { get; set; }
|
public object Message { get; set; }
|
||||||
public ResponseHandlerInfo ResponseHandlerInfo { get; set; }
|
public ResponseHandlerInfo ResponseHandlerInfo { get; set; }
|
||||||
@ -214,15 +225,13 @@ namespace Tapeti.Flow.Default
|
|||||||
|
|
||||||
|
|
||||||
private readonly IConfig config;
|
private readonly IConfig config;
|
||||||
private readonly IFlowStore flowStore;
|
private readonly SendRequestFunc sendRequest;
|
||||||
private readonly Func<FlowContext, object, ResponseHandlerInfo, Task> sendRequest;
|
|
||||||
private readonly List<RequestInfo> requests = new List<RequestInfo>();
|
private readonly List<RequestInfo> requests = new List<RequestInfo>();
|
||||||
|
|
||||||
|
|
||||||
public ParallelRequestBuilder(IConfig config, IFlowStore flowStore, Func<FlowContext, object, ResponseHandlerInfo, Task> sendRequest)
|
public ParallelRequestBuilder(IConfig config, SendRequestFunc sendRequest)
|
||||||
{
|
{
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.flowStore = flowStore;
|
|
||||||
this.sendRequest = sendRequest;
|
this.sendRequest = sendRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,15 +262,34 @@ namespace Tapeti.Flow.Default
|
|||||||
|
|
||||||
public IYieldPoint Yield(Func<Task<IYieldPoint>> continuation)
|
public IYieldPoint Yield(Func<Task<IYieldPoint>> continuation)
|
||||||
{
|
{
|
||||||
return new YieldPoint(flowStore, true, context => Task.WhenAll(requests.Select(requestInfo => sendRequest(context, requestInfo.Message, requestInfo.ResponseHandlerInfo))));
|
return BuildYieldPoint(continuation, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public IYieldPoint Yield(Func<IYieldPoint> continuation)
|
public IYieldPoint YieldSync(Func<IYieldPoint> continuation)
|
||||||
{
|
{
|
||||||
return new YieldPoint(flowStore, true, context => Task.WhenAll(requests.Select(requestInfo => sendRequest(context, requestInfo.Message, requestInfo.ResponseHandlerInfo))));
|
return BuildYieldPoint(continuation, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IYieldPoint BuildYieldPoint(Delegate convergeMethod, bool convergeMethodSync)
|
||||||
|
{
|
||||||
|
if (convergeMethod?.Method == null)
|
||||||
|
throw new ArgumentNullException(nameof(convergeMethod));
|
||||||
|
|
||||||
|
return new DelegateYieldPoint(true, context =>
|
||||||
|
{
|
||||||
|
if (convergeMethod.Method.DeclaringType != context.MessageContext.Controller.GetType())
|
||||||
|
throw new YieldPointException("Converge method must be in the same controller class");
|
||||||
|
|
||||||
|
return Task.WhenAll(requests.Select(requestInfo =>
|
||||||
|
sendRequest(context, requestInfo.Message,
|
||||||
|
requestInfo.ResponseHandlerInfo,
|
||||||
|
convergeMethod.Method.Name,
|
||||||
|
convergeMethodSync)));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
internal class ResponseHandlerInfo
|
internal class ResponseHandlerInfo
|
||||||
|
@ -81,6 +81,7 @@ namespace Tapeti.Flow.Default
|
|||||||
{
|
{
|
||||||
public string MethodName { get; set; }
|
public string MethodName { get; set; }
|
||||||
public string ConvergeMethodName { get; set; }
|
public string ConvergeMethodName { get; set; }
|
||||||
|
public bool ConvergeMethodSync { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public ContinuationMetadata Clone()
|
public ContinuationMetadata Clone()
|
||||||
@ -88,7 +89,8 @@ namespace Tapeti.Flow.Default
|
|||||||
return new ContinuationMetadata
|
return new ContinuationMetadata
|
||||||
{
|
{
|
||||||
MethodName = MethodName,
|
MethodName = MethodName,
|
||||||
ConvergeMethodName = ConvergeMethodName
|
ConvergeMethodName = ConvergeMethodName,
|
||||||
|
ConvergeMethodSync = ConvergeMethodSync
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
Tapeti.Flow/Default/IInternalYieldPoint.cs
Normal file
15
Tapeti.Flow/Default/IInternalYieldPoint.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Tapeti.Flow.Default
|
||||||
|
{
|
||||||
|
internal interface IStateYieldPoint : IYieldPoint
|
||||||
|
{
|
||||||
|
bool StoreState { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal interface IExecutableYieldPoint : IYieldPoint
|
||||||
|
{
|
||||||
|
Task Execute(FlowContext context);
|
||||||
|
}
|
||||||
|
}
|
13
Tapeti.Flow/Default/StateYieldPoint.cs
Normal file
13
Tapeti.Flow/Default/StateYieldPoint.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
namespace Tapeti.Flow.Default
|
||||||
|
{
|
||||||
|
internal class StateYieldPoint : IStateYieldPoint
|
||||||
|
{
|
||||||
|
public bool StoreState { get; }
|
||||||
|
|
||||||
|
|
||||||
|
public StateYieldPoint(bool storeState)
|
||||||
|
{
|
||||||
|
StoreState = storeState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,7 @@ namespace Tapeti.Flow
|
|||||||
IFlowParallelRequestBuilder AddRequestSync<TRequest, TResponse>(TRequest message, Action<TResponse> responseHandler);
|
IFlowParallelRequestBuilder AddRequestSync<TRequest, TResponse>(TRequest message, Action<TResponse> responseHandler);
|
||||||
|
|
||||||
IYieldPoint Yield(Func<Task<IYieldPoint>> continuation);
|
IYieldPoint Yield(Func<Task<IYieldPoint>> continuation);
|
||||||
IYieldPoint Yield(Func<IYieldPoint> continuation);
|
IYieldPoint YieldSync(Func<IYieldPoint> continuation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IYieldPoint
|
public interface IYieldPoint
|
||||||
|
@ -56,9 +56,11 @@
|
|||||||
<Compile Include="Default\FlowContext.cs" />
|
<Compile Include="Default\FlowContext.cs" />
|
||||||
<Compile Include="Default\FlowMessageMiddleware.cs" />
|
<Compile Include="Default\FlowMessageMiddleware.cs" />
|
||||||
<Compile Include="Default\FlowState.cs" />
|
<Compile Include="Default\FlowState.cs" />
|
||||||
|
<Compile Include="Default\IInternalYieldPoint.cs" />
|
||||||
<Compile Include="Default\NonPersistentFlowRepository.cs" />
|
<Compile Include="Default\NonPersistentFlowRepository.cs" />
|
||||||
<Compile Include="Default\DelegateYieldPoint.cs" />
|
<Compile Include="Default\DelegateYieldPoint.cs" />
|
||||||
<Compile Include="ConfigExtensions.cs" />
|
<Compile Include="ConfigExtensions.cs" />
|
||||||
|
<Compile Include="Default\StateYieldPoint.cs" />
|
||||||
<Compile Include="FlowHelpers\MethodSerializer.cs" />
|
<Compile Include="FlowHelpers\MethodSerializer.cs" />
|
||||||
<Compile Include="FlowMiddleware.cs" />
|
<Compile Include="FlowMiddleware.cs" />
|
||||||
<Compile Include="Default\FlowStore.cs" />
|
<Compile Include="Default\FlowStore.cs" />
|
||||||
|
@ -36,23 +36,42 @@ namespace Test
|
|||||||
Console.WriteLine(">> Marco (yielding with request)");
|
Console.WriteLine(">> Marco (yielding with request)");
|
||||||
|
|
||||||
await myVisualizer.VisualizeMarco();
|
await myVisualizer.VisualizeMarco();
|
||||||
|
StateTestGuid = Guid.NewGuid();
|
||||||
|
|
||||||
return flowProvider.YieldWithRequestSync<PoloConfirmationRequestMessage, PoloConfirmationResponseMessage>(
|
return flowProvider.YieldWithParallelRequest()
|
||||||
new PoloConfirmationRequestMessage()
|
.AddRequestSync<PoloConfirmationRequestMessage, PoloConfirmationResponseMessage>(new PoloConfirmationRequestMessage
|
||||||
{
|
{
|
||||||
StoredInState = StateTestGuid
|
StoredInState = StateTestGuid
|
||||||
},
|
}, HandlePoloConfirmationResponse1)
|
||||||
HandlePoloConfirmationResponse);
|
|
||||||
|
.AddRequestSync<PoloConfirmationRequestMessage, PoloConfirmationResponseMessage>(new PoloConfirmationRequestMessage
|
||||||
|
{
|
||||||
|
StoredInState = StateTestGuid
|
||||||
|
}, HandlePoloConfirmationResponse2)
|
||||||
|
|
||||||
|
.YieldSync(ContinuePoloConfirmation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Continuation]
|
[Continuation]
|
||||||
public IYieldPoint HandlePoloConfirmationResponse(PoloConfirmationResponseMessage message)
|
public void HandlePoloConfirmationResponse1(PoloConfirmationResponseMessage message)
|
||||||
{
|
{
|
||||||
Console.WriteLine(">> HandlePoloConfirmationResponse (ending flow)");
|
Console.WriteLine(">> HandlePoloConfirmationResponse1");
|
||||||
|
|
||||||
Console.WriteLine(message.ShouldMatchState.Equals(StateTestGuid) ? "Confirmed!" : "Oops! Mismatch!");
|
Console.WriteLine(message.ShouldMatchState.Equals(StateTestGuid) ? "Confirmed!" : "Oops! Mismatch!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[Continuation]
|
||||||
|
public void HandlePoloConfirmationResponse2(PoloConfirmationResponseMessage message)
|
||||||
|
{
|
||||||
|
Console.WriteLine(">> HandlePoloConfirmationResponse2");
|
||||||
|
Console.WriteLine(message.ShouldMatchState.Equals(StateTestGuid) ? "Confirmed!" : "Oops! Mismatch!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private IYieldPoint ContinuePoloConfirmation()
|
||||||
|
{
|
||||||
|
Console.WriteLine("> ConvergePoloConfirmation (ending flow)");
|
||||||
return flowProvider.EndWithResponse(new PoloMessage());
|
return flowProvider.EndWithResponse(new PoloMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +96,6 @@ namespace Test
|
|||||||
public void Polo(PoloMessage message)
|
public void Polo(PoloMessage message)
|
||||||
{
|
{
|
||||||
Console.WriteLine(">> Polo");
|
Console.WriteLine(">> Polo");
|
||||||
StateTestGuid = Guid.NewGuid();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,8 +17,9 @@ namespace Test
|
|||||||
|
|
||||||
public async Task Run()
|
public async Task Run()
|
||||||
{
|
{
|
||||||
// await publisher.Publish(new MarcoMessage());
|
await publisher.Publish(new MarcoMessage());
|
||||||
|
|
||||||
|
/*
|
||||||
var concurrent = new SemaphoreSlim(20);
|
var concurrent = new SemaphoreSlim(20);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@ -38,12 +39,12 @@ namespace Test
|
|||||||
|
|
||||||
await Task.Delay(200);
|
await Task.Delay(200);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,11 @@ namespace Test
|
|||||||
})
|
})
|
||||||
{
|
{
|
||||||
Console.WriteLine("Subscribing...");
|
Console.WriteLine("Subscribing...");
|
||||||
connection.Subscribe().Wait();
|
var subscriber = connection.Subscribe(false).Result;
|
||||||
|
|
||||||
|
Console.WriteLine("Consuming...");
|
||||||
|
subscriber.Resume().Wait();
|
||||||
|
|
||||||
Console.WriteLine("Done!");
|
Console.WriteLine("Done!");
|
||||||
|
|
||||||
var emitter = container.GetInstance<MarcoEmitter>();
|
var emitter = container.GetInstance<MarcoEmitter>();
|
||||||
|
@ -59,6 +59,10 @@
|
|||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Tapeti.Annotations\Tapeti.Annotations.csproj">
|
||||||
|
<Project>{c4897d64-d04e-4ae9-bd98-d64295d1d13a}</Project>
|
||||||
|
<Name>Tapeti.Annotations</Name>
|
||||||
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\Tapeti.Flow.SQL\Tapeti.Flow.SQL.csproj">
|
<ProjectReference Include="..\Tapeti.Flow.SQL\Tapeti.Flow.SQL.csproj">
|
||||||
<Project>{6de7b122-eb6a-46b8-aeaf-f84dde18f9c7}</Project>
|
<Project>{6de7b122-eb6a-46b8-aeaf-f84dde18f9c7}</Project>
|
||||||
<Name>Tapeti.Flow.SQL</Name>
|
<Name>Tapeti.Flow.SQL</Name>
|
||||||
|
Loading…
Reference in New Issue
Block a user