/// <summary> /// Starts the endpoint and returns a reference to it. /// </summary> /// <param name="startableEndpoint">The startable endpoint.</param> /// <param name="serviceProvider">The container specific service provider factory.</param> /// <returns>A reference to the endpoint.</returns> public static Task <IEndpointInstance> Start(this IStartableEndpointWithExternallyManagedContainer startableEndpoint, IServiceProvider serviceProvider) { Guard.AgainstNull(nameof(startableEndpoint), startableEndpoint); Guard.AgainstNull(nameof(serviceProvider), serviceProvider); return(startableEndpoint.Start(new ServiceProviderAdapter(serviceProvider))); }
public async Task Should_use_it_for_component_resolution() { var container = new AcceptanceTestingContainer(); container.RegisterSingleton(typeof(MyComponent), myComponent); var result = await Scenario.Define <Context>() .WithEndpoint <ExternallyManagedContainerEndpoint>(b => { IStartableEndpointWithExternallyManagedContainer configuredEndpoint = null; b.ToCreateInstance( config => { configuredEndpoint = EndpointWithExternallyManagedContainer.Create(config, new RegistrationPhaseAdapter(container)); return(Task.FromResult(configuredEndpoint)); }, configured => configured.Start(new ResolutionPhaseAdapter(container)) ) .When((e, c) => { c.BuilderWasResolvable = container.Build(typeof(IBuilder)) != null; //use the session provided by configure to make sure its properly populated return(configuredEndpoint.MessageSession.Value.SendLocal(new SomeMessage())); }); }) .Done(c => c.Message != null) .Run(); Assert.AreEqual(result.Message, myComponent.Message); Assert.True(result.BuilderWasResolvable, "IBuilder should be resolvable in the container"); Assert.False(container.WasDisposed, "Externally managed containers should not be disposed"); }
public NserviceBusEndpoint(string endPointName, IServiceCollection services) { endpointConfiguration = new EndpointConfiguration(endPointName); endpointConfiguration.UseTransport <LearningTransport>(); startableEndPoint = EndpointWithExternallyManagedServiceProvider .Create(endpointConfiguration, services); }
public async Task Should_use_it_for_component_resolution() { var serviceCollection = new ServiceCollection(); serviceCollection.AddSingleton(typeof(MyComponent), myComponent); var result = await Scenario.Define <Context>() .WithEndpoint <ExternallyManagedContainerEndpoint>(b => { IStartableEndpointWithExternallyManagedContainer configuredEndpoint = null; b.ToCreateInstance( config => { configuredEndpoint = EndpointWithExternallyManagedContainer.Create(config, serviceCollection); return(Task.FromResult(configuredEndpoint)); }, configured => configured.Start(serviceCollection.BuildServiceProvider()) ) .When((e, c) => { //use the session provided by configure to make sure its properly populated return(configuredEndpoint.MessageSession.Value.SendLocal(new SomeMessage())); }); }) .Done(c => c.MessageReceived) .Run(); Assert.NotNull(result.ServiceProvider, "IServiceProvider should be injectable"); Assert.AreSame(myComponent, result.CustomService, "Should inject custom services"); }
public InProcessFunctionEndpoint( IStartableEndpointWithExternallyManagedContainer externallyManagedContainerEndpoint, ServiceBusTriggeredEndpointConfiguration configuration, IServiceProvider serviceProvider) { this.configuration = configuration; endpointFactory = _ => externallyManagedContainerEndpoint.Start(serviceProvider); }
public NServiceBusHostedService(IStartableEndpointWithExternallyManagedContainer startableEndpoint, IServiceProvider serviceProvider, ILoggerFactory loggerFactory, DeferredLoggerFactory deferredLoggerFactory, HostAwareMessageSession hostAwareMessageSession) { this.loggerFactory = loggerFactory; this.deferredLoggerFactory = deferredLoggerFactory; this.hostAwareMessageSession = hostAwareMessageSession; this.startableEndpoint = startableEndpoint; this.serviceProvider = serviceProvider; }
public NServiceBusService(IStartableEndpointWithExternallyManagedContainer startableEndpoint, IServiceProvider serviceProvider) { this.startableEndpoint = startableEndpoint; this.serviceProvider = serviceProvider; }
public static async Task <IEndpointInstance> Start(IStartableEndpointWithExternallyManagedContainer nsb) { BusOnline = false; Instance = await nsb.Start(new Internal.ContainerAdapter(Configuration.Settings.Container)).ConfigureAwait(false); // Take IEndpointInstance and pull out the info we need for eventstore consuming // We want eventstore to push message directly into NSB // That way we can have all the fun stuff like retries, error queues, incoming/outgoing mutators etc // But NSB doesn't have a way to just insert a message directly into the pipeline // You can SendLocal which will send the event out to the transport then back again but in addition to being a // waste of time its not safe incase this instance goes down because we'd have ACKed the event now sitting // unprocessed on the instance specific queue. // // The only way I can find to call into the pipeline directly is to highjack these private fields on // the transport receiver. try { var receiveComponent = Instance.GetType() .GetField("receiveComponent", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(Instance); var receivers = ( (IEnumerable) // ReSharper disable once PossibleNullReferenceException receiveComponent.GetType() .GetField("receivers", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(receiveComponent)).Cast <object>(); object main = null; foreach (var receiver in receivers) { var id = (string) receiver.GetType() .GetProperty("Id", BindingFlags.Public | BindingFlags.Instance) .GetValue(receiver); if (id.ToLower() == "main") { main = receiver; break; } } if (main == null) { throw new InvalidOperationException("Could not find main receiver"); } var pipelineExecutor = main.GetType() .GetField("pipelineExecutor", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(main); var recoverabilityExecutor = main.GetType() .GetField("recoverabilityExecutor", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(main); var mainPipeline = pipelineExecutor .GetType() .GetField("mainPipeline", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(pipelineExecutor); var behaviors = mainPipeline .GetType() .GetField("behaviors", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(mainPipeline) as IBehavior[]; var pipelineMethod = pipelineExecutor.GetType().GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public) .MakeFuncDelegateWithTarget <MessageContext, Task>(pipelineExecutor.GetType()); OnMessage = (c) => pipelineMethod(pipelineExecutor, c); var recoverabilityMethod = recoverabilityExecutor.GetType() .GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public) .MakeFuncDelegateWithTarget <ErrorContext, Task <ErrorHandleResult> >(recoverabilityExecutor.GetType()); OnError = (c) => recoverabilityMethod(recoverabilityExecutor, c); PushSettings = (PushRuntimeSettings)main.GetType() .GetField("pushRuntimeSettings", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(main); Logger.InfoEvent("Online", "NServiceBus is online"); for (var i = 0; i < behaviors.Length; i++) { Logger.DebugEvent("PipelineStep", "{Index}: {StepType}", i, behaviors[i].GetType().FullName); } BusOnline = true; return(Instance); } catch (Exception e) { throw new InvalidOperationException("Could not hack into NSB - event consumer won't work", e); } }
public static Configure NServiceBus(this Configure config, EndpointConfiguration endpointConfig) { IStartableEndpointWithExternallyManagedContainer startableEndpoint = null; { var settings = endpointConfig.GetSettings(); var conventions = endpointConfig.Conventions(); // set the configured endpoint name to the one NSB config was constructed with config.SetEndpointName(settings.Get <string>("NServiceBus.Routing.EndpointName")); conventions.DefiningCommandsAs(type => typeof(Messages.ICommand).IsAssignableFrom(type)); conventions.DefiningEventsAs(type => typeof(Messages.IEvent).IsAssignableFrom(type)); conventions.DefiningMessagesAs(type => typeof(Messages.IMessage).IsAssignableFrom(type)); endpointConfig.AssemblyScanner().ScanAppDomainAssemblies = true; endpointConfig.EnableCallbacks(); endpointConfig.EnableInstallers(); endpointConfig.UseSerialization <Internal.AggregatesSerializer>(); endpointConfig.EnableFeature <Feature>(); } config.RegistrationTasks.Add(c => { var container = c.Container; container.Register(factory => new Aggregates.Internal.DelayedRetry(factory.Resolve <IMetrics>(), factory.Resolve <IMessageDispatcher>()), Lifestyle.Singleton); container.Register <IEventMapper>((factory) => new EventMapper(factory.Resolve <IMessageMapper>()), Lifestyle.Singleton); container.Register <UnitOfWork.IDomain>((factory) => new NSBUnitOfWork(factory.Resolve <IRepositoryFactory>(), factory.Resolve <IEventFactory>(), factory.Resolve <IVersionRegistrar>()), Lifestyle.UnitOfWork); container.Register <IEventFactory>((factory) => new EventFactory(factory.Resolve <IMessageMapper>()), Lifestyle.Singleton); container.Register <IMessageDispatcher>((factory) => new Dispatcher(factory.Resolve <IMetrics>(), factory.Resolve <IMessageSerializer>(), factory.Resolve <IEventMapper>(), factory.Resolve <IVersionRegistrar>()), Lifestyle.Singleton); container.Register <IMessaging>((factory) => new NServiceBusMessaging(factory.Resolve <MessageHandlerRegistry>(), factory.Resolve <MessageMetadataRegistry>(), factory.Resolve <ReadOnlySettings>()), Lifestyle.Singleton); var settings = endpointConfig.GetSettings(); settings.Set("Retries", config.Retries); settings.Set("SlowAlertThreshold", config.SlowAlertThreshold); settings.Set("CommandDestination", config.CommandDestination); // Set immediate retries to 0 - we handle retries ourselves any message which throws should be sent to error queue endpointConfig.Recoverability().Immediate(x => { x.NumberOfRetries(0); }); endpointConfig.Recoverability().Delayed(x => { x.NumberOfRetries(0); }); endpointConfig.MakeInstanceUniquelyAddressable(c.UniqueAddress); endpointConfig.LimitMessageProcessingConcurrencyTo(c.ParallelMessages); // NSB doesn't have an endpoint name setter other than the constructor, hack it in settings.Set("NServiceBus.Routing.EndpointName", c.Endpoint); startableEndpoint = EndpointWithExternallyManagedContainer.Create(endpointConfig, new Internal.ContainerAdapter()); return(Task.CompletedTask); }); // Split creating the endpoint and starting the endpoint into 2 seperate jobs for certain (MICROSOFT) DI setup config.SetupTasks.Add((c) => { return(Aggregates.Bus.Start(startableEndpoint)); }); return(config); }
public NServiceBusHostedService(IStartableEndpointWithExternallyManagedContainer startableEndpoint) { this.startableEndpoint = startableEndpoint; }