Skip to content

Instantly share code, notes, and snippets.

@haf
Created May 24, 2012 19:54
Show Gist options
  • Save haf/2783842 to your computer and use it in GitHub Desktop.
Save haf/2783842 to your computer and use it in GitHub Desktop.
Passing contexts onwards
public interface IMessageTypeConverter
{
bool Contains(Type messageType);
bool TryConvert<T>(out T message)
where T : class;
IDictionary<Type, object> Enumerate();
}
static class MyContextExtensions
{
public static void AttachAmbientContextsFrom<T>(this ISendContext target,
IConsumeContext<T> source)
where T : class
{
source.GetMessageContexts()
.ToList()
.ForEach(ctx => target.AttachMessageIn(ctx));
}
static IEnumerable<IConsumeContext> GetMessageContexts<T>(this IConsumeContext<T> sendContext)
where T : class
{
var converter = (IMessageTypeConverter)sendContext.GetType().GetField("_typeConverter", BindingFlags.NonPublic | BindingFlags.FlattenHierarchy).GetValue(sendContext);
var contexts =
converter.Enumerate()
.Select(kv =>
{
var newContext = typeof (ConsumeContext<>).MakeGenericType(kv.Key);
return FastActivator.Create(newContext, sendContext, kv.Value) as IConsumeContext;
});
return contexts;
}
}
public class ForwardingAuthenticationContext_spec
{
readonly Future<Cmd> _cmdReceived
= new Future<Cmd>();
readonly Future<IConsumeContext<AfterwardsEvent>> _eventContext
= new Future<IConsumeContext<AfterwardsEvent>>();
IServiceBus _receiver;
IServiceBus _sender;
SubscriptionLoopback _receiverLoopback;
SubscriptionLoopback _remoteLoopback;
[Given]
public void receive_on_bus()
{
_receiver = ServiceBusFactory.New(sbc =>
{
ConfigureReceiver(sbc);
sbc.Subscribe(s => s.Handler<Cmd>((ctx, msg) =>
{
_cmdReceived.Complete(msg);
ctx.Bus.Publish(new AfterwardsImpl(), pubCtx =>
{
pubCtx.AttachAmbientContextsFrom(ctx);
});
}));
});
_sender = ServiceBusFactory.New(sbc =>
{
ConfigureSender(sbc);
sbc.Subscribe(s => s.Handler<AfterwardsEvent>((ctx, msg) =>
_eventContext.Complete(ctx)));
});
_receiverLoopback.SetTargetCoordinator(_remoteLoopback.Router);
_remoteLoopback.SetTargetCoordinator(_receiverLoopback.Router);
_sender.Publish(new CmdImpl
{
XX = "xs",
Piggybacking = "Ms. Piggy"
});
}
[Then]
public void sender_should_eventually_get_event()
{
_eventContext.WaitUntilCompleted(8.Seconds())
.ShouldBeTrue("we should be getting an event back");
IConsumeContext<OutOfBand> oobCtx;
_eventContext.Value.BaseContext.TryGetContext(out oobCtx)
.ShouldBeTrue("Since we moved the out of band data over as a part of the " +
"transfer, it should still be here.");
}
[Finally]
public void Dispose()
{
_sender.Dispose();
_sender = null;
_receiver.Dispose();
_receiver = null;
}
void ConfigureReceiver(ServiceBusConfigurator sbc)
{
sbc.ReceiveFrom("loopback://localhost/Receiver");
sbc.AddSubscriptionObserver((bus, coordinator) =>
{
_receiverLoopback = new SubscriptionLoopback(bus, coordinator);
return _receiverLoopback;
});
}
void ConfigureSender(ServiceBusConfigurator sbc)
{
sbc.ReceiveFrom("loopback://localhost/Sender");
sbc.AddSubscriptionObserver((bus, coordinator) =>
{
_remoteLoopback = new SubscriptionLoopback(bus, coordinator);
return _remoteLoopback;
});
}
}
class CmdImpl
: Cmd, OutOfBand
{
public string XX { get; set; }
public string Piggybacking { get; set; }
}
class AfterwardsImpl
: AfterwardsEvent
{
}
interface AfterwardsEvent
{
}
interface Cmd
{
string XX { get; }
}
interface OutOfBand
{
string Piggybacking { get; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment