Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7870293
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 3, 20262026-06-03T01:34:34+00:00 2026-06-03T01:34:34+00:00

Using simple injector with the command pattern described here and the query pattern described

  • 0

Using simple injector with the command pattern described here and the query pattern described here. For one of the commands, I have 2 handler implementations. The first is a “normal” implementation that executes synchronously:

public class SendEmailMessageHandler
    : IHandleCommands<SendEmailMessageCommand>
{
    public SendEmailMessageHandler(IProcessQueries queryProcessor
        , ISendMail mailSender
        , ICommandEntities entities
        , IUnitOfWork unitOfWork
        , ILogExceptions exceptionLogger)
    {
        // save constructor args to private readonly fields
    }

    public void Handle(SendEmailMessageCommand command)
    {
        var emailMessageEntity = GetThisFromQueryProcessor(command);
        var mailMessage = ConvertEntityToMailMessage(emailMessageEntity);
        _mailSender.Send(mailMessage);
        emailMessageEntity.SentOnUtc = DateTime.UtcNow;
        _entities.Update(emailMessageEntity);
        _unitOfWork.SaveChanges();
    }
}

The other is like a command decorator, but explicitly wraps the previous class to execute the command in a separate thread:

public class SendAsyncEmailMessageHandler 
    : IHandleCommands<SendEmailMessageCommand>
{
    public SendAsyncEmailMessageHandler(ISendMail mailSender, 
        ILogExceptions exceptionLogger)
    {
        // save constructor args to private readonly fields
    }

    public void Handle(SendEmailMessageCommand command)
    {
        var program = new SendAsyncEmailMessageProgram
            (command, _mailSender, _exceptionLogger);
        var thread = new Thread(program.Launch);
        thread.Start();
    }

    private class SendAsyncEmailMessageProgram
    {
        internal SendAsyncEmailMessageProgram(
            SendEmailMessageCommand command
            , ISendMail mailSender
            , ILogExceptions exceptionLogger)
        {
            // save constructor args to private readonly fields
        }

        internal void Launch()
        {
            // get new instances of DbContext and query processor
            var uow = MyServiceLocator.Current.GetService<IUnitOfWork>();
            var qp = MyServiceLocator.Current.GetService<IProcessQueries>();
            var handler = new SendEmailMessageHandler(qp, _mailSender, 
                uow as ICommandEntities, uow, _exceptionLogger);
            handler.Handle(_command);
        }
    }
}

For a while simpleinjector was yelling at me, telling me that it found 2 implementations of IHandleCommands<SendEmailMessageCommand>. I found that the following works, but not sure whether it is the best / optimal way. I want to explicitly register this one interface to use the Async implementation:

container.RegisterManyForOpenGeneric(typeof(IHandleCommands<>), 
    (type, implementations) =>
    {
        // register the async email handler
        if (type == typeof(IHandleCommands<SendEmailMessageCommand>))
            container.Register(type, implementations
                .Single(i => i == typeof(SendAsyncEmailMessageHandler)));

        else if (implementations.Length < 1)
            throw new InvalidOperationException(string.Format(
                "No implementations were found for type '{0}'.",
                    type.Name));
        else if (implementations.Length > 1)
            throw new InvalidOperationException(string.Format(
                "{1} implementations were found for type '{0}'.",
                    type.Name, implementations.Length));

        // register a single implementation (default behavior)
        else
            container.Register(type, implementations.Single());

    }, assemblies);

My question: is this the right way, or is there something better? For example, I’d like to reuse the existing exceptions thrown by Simpleinjector for all other implementations instead of having to throw them explicitly in the callback.

Update reply to Steven’s answer

I have updated my question to be more explicit. The reason I have implemented it this way is because as part of the operation, the command updates a System.Nullable<DateTime> property called SentOnUtc on a db entity after the MailMessage is successfully sent.

The ICommandEntities and IUnitOfWork are both implemented by an entity framework DbContext class.The DbContext is registered per http context, using the method described here:

container.RegisterPerWebRequest<MyDbContext>();
container.Register<IUnitOfWork>(container.GetInstance<MyDbContext>);
container.Register<IQueryEntities>(container.GetInstance<MyDbContext>);
container.Register<ICommandEntities>(container.GetInstance<MyDbContext>);

The default behavior of the RegisterPerWebRequest extension method in the simpleinjector wiki is to register a transient instance when the HttpContext is null (which it will be in the newly launched thread).

var context = HttpContext.Current;
if (context == null)
{
    // No HttpContext: Let's create a transient object.
    return _instanceCreator();
...

This is why the Launch method uses the service locator pattern to get a single instance of DbContext, then passes it directly to the synchronous command handler constructor. In order for the _entities.Update(emailMessageEntity) and _unitOfWork.SaveChanges() lines to work, both must be using the same DbContext instance.

NOTE: Ideally, sending the email should be handled by a separate polling worker. This command is basically a queue clearing house. The EmailMessage entities in the db already have all of the information needed to send the email. This command just grabs an unsent one from the database, sends it, then records the DateTime of the action. Such a command could be executed by polling from a different process / app, but I will not accept such an answer for this question. For now, we need to kick off this command when some kind of http request event triggers it.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-03T01:34:37+00:00Added an answer on June 3, 2026 at 1:34 am

    There are indeed easier ways to do this. For instance, instead of registering a BatchRegistrationCallback as you did in your last code snippet, you can make use of the OpenGenericBatchRegistrationExtensions.GetTypesToRegister method. This method is used internally by the RegisterManyForOpenGeneric methods, and allows you to filter the returned types before you send them to an RegisterManyForOpenGeneric overload:

    var types = OpenGenericBatchRegistrationExtensions
        .GetTypesToRegister(typeof(IHandleCommands<>), assemblies)
        .Where(t => !t.Name.StartsWith("SendAsync"));
    
    container.RegisterManyForOpenGeneric(
        typeof(IHandleCommands<>), 
        types);
    

    But I think it would be better to make a few changes to your design. When you change your async command handler to a generic decorator, you completely remove the problem altogether. Such a generic decorator could look like this:

    public class SendAsyncCommandHandlerDecorator<TCommand>
        : IHandleCommands<TCommand>
    {
        private IHandleCommands<TCommand> decorated;
    
        public SendAsyncCommandHandlerDecorator(
             IHandleCommands<TCommand> decorated)
        {
            this.decorated = decorated;
        }
    
        public void Handle(TCommand command)
        {
            // WARNING: THIS CODE IS FLAWED!!
            Task.Factory.StartNew(
                () => this.decorated.Handle(command));
        }
    }
    

    Note that this decorator is flawed because of reasons I’ll explain later, but let’s go with this for the sake of education.

    Making this type generic, allows you to reuse this type for multiple commands. Because this type is generic, the RegisterManyForOpenGeneric will skip this (since it can’t guess the generic type). This allows you to register the decorator as follows:

    container.RegisterDecorator(
        typeof(IHandleCommands<>), 
        typeof(SendAsyncCommandHandler<>));
    

    In your case however, you don’t want this decorator to be wrapped around all handlers (as the previous registration does). There is an RegisterDecorator overload that takes a predicate, that allows you to specify when to apply this decorator:

    container.RegisterDecorator(
        typeof(IHandleCommands<>), 
        typeof(SendAsyncCommandHandlerDecorator<>),
        c => c.ServiceType == typeof(IHandleCommands<SendEmailMessageCommand>));
    

    With this predicate applied, the SendAsyncCommandHandlerDecorator<T> will only be applied to the IHandleCommands<SendEmailMessageCommand> handler.

    Another option (which I prefer) is to register a closed generic version of the SendAsyncCommandHandlerDecorator<T> version. This saves you from having to specify the predicate:

    container.RegisterDecorator(
        typeof(IHandleCommands<>), 
        typeof(SendAsyncCommandHandler<SendEmailMessageCommand>));
    

    As I noted however, the code for the given decorator is flawed, because you should always build a new dependency graph on a new thread, and never pass on dependencies from thread to thread (which the original decorator does). More information about this in this article: How to work with dependency injection in multi-threaded applications.

    So the answer is actually more complex, since this generic decorator should really be a proxy that replaces the original command handler (or possibly even a chain of decorators wrapping a handler). This proxy must be able to build up a new object graph in a new thread. This proxy would look like this:

    public class SendAsyncCommandHandlerProxy<TCommand>
        : IHandleCommands<TCommand>
    {
        Func<IHandleCommands<TCommand>> factory;
    
        public SendAsyncCommandHandlerProxy(
             Func<IHandleCommands<TCommand>> factory)
        {
            this.factory = factory;
        }
    
        public void Handle(TCommand command)
        {
            Task.Factory.StartNew(() =>
            {
                var handler = this.factory();
                handler.Handle(command);
            });
        }
    }
    

    Although Simple Injector has no built-in support for resolving Func<T> factory, the RegisterDecorator methods are the exception. The reason for this is that it would be very tedious to register decorators with Func dependencies without framework support. In other words, when registering the SendAsyncCommandHandlerProxy with the RegisterDecorator method, Simple Injector will automatically inject a Func<T> delegate that can create new instances of the decorated type. Since the proxy only refences a (singleton) factory (and is stateless), we can even register it as singleton:

    container.RegisterSingleDecorator(
        typeof(IHandleCommands<>), 
        typeof(SendAsyncCommandHandlerProxy<SendEmailMessageCommand>));
    

    Obviously, you can mix this registration with other RegisterDecorator registrations. Example:

    container.RegisterManyForOpenGeneric(
        typeof(IHandleCommands<>),
        typeof(IHandleCommands<>).Assembly);
    
    container.RegisterDecorator(
        typeof(IHandleCommands<>),
        typeof(TransactionalCommandHandlerDecorator<>));
    
    container.RegisterSingleDecorator(
        typeof(IHandleCommands<>), 
        typeof(SendAsyncCommandHandlerProxy<SendEmailMessageCommand>));
    
    container.RegisterDecorator(
        typeof(IHandleCommands<>),
        typeof(ValidatableCommandHandlerDecorator<>));
    

    This registration wraps any command handler with a TransactionalCommandHandlerDecorator<T>, optionally decorates it with the async proxy, and always wraps it with a ValidatableCommandHandlerDecorator<T>. This allows you to do the validation synchronously (on the same thread), and when validation succeeds, spin of handling of the command on a new thread, running in a transaction on that thread.

    Since some of your dependencies are registered Per Web Request, this means that they would get a new (transient) instance an exception is thrown when there is no web request, which is they way this is implemented in the Simple Injector (as is the case when you start a new thread to run the code). As you are implementing multiple interfaces with your EF DbContext, this means Simple Injector will create a new instance for each constructor-injected interface, and as you said, this will be a problem.

    You’ll need to reconfigure the DbContext, since a pure Per Web Request will not do. There are several solutions, but I think the best is to make an hybrid PerWebRequest/PerLifetimeScope instance. You’ll need the Per Lifetime Scope extension package for this. Also note that also is an extension package for Per Web Request, so you don’t have to use any custom code. When you’ve done this, you can define the following registration:

    container.RegisterPerWebRequest<DbContext, MyDbContext>();
    container.RegisterPerLifetimeScope<IObjectContextAdapter,
        MyDbContext>();
    
    // Register as hybrid PerWebRequest / PerLifetimeScope.
    container.Register<MyDbContext>(() =>
    {
        if (HttpContext.Current != null)
            return (MyDbContext)container.GetInstance<DbContext>();
        else
            return (MyDbContext)container
                .GetInstance<IObjectContextAdapter>();
    });
    

    UPDATE
    Simple Injector 2 now has the explicit notion of lifestyles and this makes the previous registration much easier. The following registration is therefore adviced:

    var hybrid = Lifestyle.CreateHybrid(
        lifestyleSelector: () => HttpContext.Current != null,
        trueLifestyle: new WebRequestLifestyle(),
        falseLifestyle: new LifetimeScopeLifestyle());
    
    // Register as hybrid PerWebRequest / PerLifetimeScope.
    container.Register<MyDbContext, MyDbContext>(hybrid);
    

    Since the Simple Injector only allows registering a type once (it doesn’t support keyed registration), it is not possible to register a MyDbContext with both a PerWebRequest lifestyle, AND a PerLifetimeScope lifestyle. So we have to cheat a bit, so we make two registrations (one per lifestyle) and select different service types (DbContext and IObjectContextAdapter). The service type is not really important, except that MyDbContext must implement/inherit from that service type (feel free to implement dummy interfaces on your MyDbContext if this is convenient).

    Besides these two registrations, we need a third registration, a mapping, that allows us to get the proper lifestyle back. This is the Register<MyDbContext> which gets the proper instance back based on whether the operation is executed inside a HTTP request or not.

    Your AsyncCommandHandlerProxy will have to start a new lifetime scope, which is done as follows:

    public class AsyncCommandHandlerProxy<T>
        : IHandleCommands<T>
    {
        private readonly Func<IHandleCommands<T>> factory;
        private readonly Container container;
    
        public AsyncCommandHandlerProxy(
            Func<IHandleCommands<T>> factory,
            Container container)
        {
            this.factory = factory;
            this.container = container;
        }
    
        public void Handle(T command)
        {
            Task.Factory.StartNew(() =>
            {
                using (this.container.BeginLifetimeScope())
                {
                    var handler = this.factory();
                    handler.Handle(command);
                }            
            });    
        }    
    }
    

    Note that the container is added as dependency of the AsyncCommandHandlerProxy.

    Now, any MyDbContext instance that is resolved when HttpContext.Current is null, will get a Per Lifetime Scope instance instead of a new transient instance.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Using simple injector with the command pattern described here . Most commands have companion
I'm using simple-modal http://www.ericmmartin.com/projects/simplemodal/ I have one modal that opens on a button click,
I have a problem using Gin. Here is a simple example. @GinModules(AppModule.class) public interface
Hi I am using the Simple Injector DI library and have been following some
I have started using Simple-form and Bootstrap and I have tried to follow this
I am using simple PHP query to fetch rows from the database, there are
iam using simple blow up trick in my page . first the div is
For several weeks I've been using the Simple Injector dependency injection container, with great
Using simple products in magento I Wish to copy a attributeset from one installation
Using simple_form , I have a simple input like this: <%= f.input :email %>

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.