using System; using System.Threading.Tasks; using SimpleInjector; using System.Reflection; using SimpleInjector.Lifestyles; namespace TestCore { class Program { public abstract class BaseDecorator : IDecoratorHandler { protected bool _isDecoratorInjected; protected IHandler _decorated; public IHandler NextHandler { get; private set; } public BaseDecorator() { } public abstract Task Handle(TIn input); public void InjectDecorator(IHandler handler) { if (_isDecoratorInjected) throw new InvalidOperationException("Decorator already has injected"); _isDecoratorInjected = true; _decorated = handler; } } public class IntegrationSenderDecorator : BaseDecorator { public IntegrationSenderDecorator() { } public override async Task Handle(TIn input) { var res = await _decorated.Handle(input); // ... return res; } } public class SaveChangesDecorator : BaseDecorator { public SaveChangesDecorator() { } public override async Task Handle(TIn input) { var res = await _decorated.Handle(input); // ... return res; } } public class OrderCreatedCmdHandler : IHandler { public OrderCreatedCmdHandler( IntegrationSenderDecorator integrationSenderDecorator, SaveChangesDecorator saveChangesDecorator) { //_pipeline = DecoratorPipelineBuilder.Create() // .Add(integrationSenderDecorator) // .Add(saveChangesDecorator) // .Build(logicHandler); // skip // analog Build code: integrationSenderDecorator.InjectDecorator(saveChangesDecorator); } public async Task Handle(string input) { return 123; } } public interface IDecoratorHandler : IHandler { IHandler NextHandler { get; } void InjectDecorator(IHandler handler); } public interface IHandler { Task Handle(TIn input); } public class IntegrationEventHandler1 { public IntegrationEventHandler1(IHandler cmdHandler) { } } public class IntegrationEventHandler2 { public IntegrationEventHandler2(IHandler cmdHandler) { } //public IntegrationEventHandler2(/*IHandler cmdHandler*/) { } // Everything is working } static void Main(string[] args) { var container = new Container(); container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle(); container.Options.DefaultLifestyle = Lifestyle.Scoped; //container.Options.DefaultLifestyle = Lifestyle.Transient; // Everything is working container.Register, OrderCreatedCmdHandler>(Lifestyle.Transient); container.Register(Lifestyle.Transient); container.Register(Lifestyle.Transient); var typesToRegister = container.GetTypesToRegister(typeof(IDecoratorHandler<,>), new Assembly[] { typeof(Program).Assembly }, new TypesToRegisterOptions { IncludeGenericTypeDefinitions = true, IncludeComposites = false }); container.Collection.Register(typeof(IDecoratorHandler<,>), typesToRegister); container.Verify(); } } }