public static IServiceCollection AddMessagePipe(this IServiceCollection services, Action <MessagePipeOptions> configure) { var options = new MessagePipeOptions(); configure(options); services.AddSingleton(options); // add as singleton instance services.AddSingleton(typeof(MessagePipeDiagnosticsInfo)); services.AddSingleton(typeof(EventFactory)); // filters. // attribute and order is deterministic at compile, so use Singleton lifetime of cache. services.AddSingleton(typeof(AttributeFilterProvider <MessageHandlerFilterAttribute>)); services.AddSingleton(typeof(AttributeFilterProvider <AsyncMessageHandlerFilterAttribute>)); services.AddSingleton(typeof(AttributeFilterProvider <RequestHandlerFilterAttribute>)); services.AddSingleton(typeof(AttributeFilterProvider <AsyncRequestHandlerFilterAttribute>)); services.AddSingleton(typeof(FilterAttachedMessageHandlerFactory)); services.AddSingleton(typeof(FilterAttachedAsyncMessageHandlerFactory)); services.AddSingleton(typeof(FilterAttachedRequestHandlerFactory)); services.AddSingleton(typeof(FilterAttachedAsyncRequestHandlerFactory)); foreach (var item in options.GetGlobalFilterTypes()) { services.TryAddTransient(item); // filter itself is Transient } #if !UNITY_2018_3_OR_NEWER // open generics implemntations(.NET Only) { var lifetime = options.InstanceLifetime; // pubsub lifetime // keyless PubSub services.Add(typeof(MessageBrokerCore <>), lifetime); services.Add(typeof(IPublisher <>), typeof(MessageBroker <>), lifetime); services.Add(typeof(ISubscriber <>), typeof(MessageBroker <>), lifetime); services.Add(typeof(BufferedMessageBrokerCore <>), lifetime); services.Add(typeof(IBufferedPublisher <>), typeof(BufferedMessageBroker <>), lifetime); services.Add(typeof(IBufferedSubscriber <>), typeof(BufferedMessageBroker <>), lifetime); // keyless PubSub async services.Add(typeof(AsyncMessageBrokerCore <>), lifetime); services.Add(typeof(IAsyncPublisher <>), typeof(AsyncMessageBroker <>), lifetime); services.Add(typeof(IAsyncSubscriber <>), typeof(AsyncMessageBroker <>), lifetime); services.Add(typeof(BufferedAsyncMessageBrokerCore <>), lifetime); services.Add(typeof(IBufferedAsyncPublisher <>), typeof(BufferedAsyncMessageBroker <>), lifetime); services.Add(typeof(IBufferedAsyncSubscriber <>), typeof(BufferedAsyncMessageBroker <>), lifetime); // keyed PubSub services.Add(typeof(MessageBrokerCore <,>), lifetime); services.Add(typeof(IPublisher <,>), typeof(MessageBroker <,>), lifetime); services.Add(typeof(ISubscriber <,>), typeof(MessageBroker <,>), lifetime); // keyed PubSub async services.Add(typeof(AsyncMessageBrokerCore <,>), lifetime); services.Add(typeof(IAsyncPublisher <,>), typeof(AsyncMessageBroker <,>), lifetime); services.Add(typeof(IAsyncSubscriber <,>), typeof(AsyncMessageBroker <,>), lifetime); } var lifetime2 = options.RequestHandlerLifetime; // requesthandler lifetime // RequestHandler services.Add(typeof(IRequestHandler <,>), typeof(RequestHandler <,>), lifetime2); services.Add(typeof(IAsyncRequestHandler <,>), typeof(AsyncRequestHandler <,>), lifetime2); // RequestAll services.Add(typeof(IRequestAllHandler <,>), typeof(RequestAllHandler <,>), lifetime2); services.Add(typeof(IAsyncRequestAllHandler <,>), typeof(AsyncRequestAllHandler <,>), lifetime2); // auto registration is .NET only. if (options.EnableAutoRegistration) { // auto register filter and requesthandler // request handler is option's lifetime, filter is transient if (options.autoregistrationAssemblies == null && options.autoregistrationTypes == null) { AddRequestHandlerAndFilterFromTypes(services, lifetime2, TypeCollector.CollectFromCurrentDomain()); } else { var fromAssemblies = (options.autoregistrationAssemblies != null) ? TypeCollector.CollectFromAssemblies(options.autoregistrationAssemblies) : Enumerable.Empty <Type>(); var types = options.autoregistrationTypes ?? Enumerable.Empty <Type>(); AddRequestHandlerAndFilterFromTypes(services, lifetime2, fromAssemblies.Concat(types).Distinct()); } } #endif return(services); }