title: What is an alternative to resolving instances by key with Simple Injector for a WPF Window mediator service?
body: <p>Looking at the "<a href="https://simpleinjector.readthedocs.org/en/latest/howto.html#resolve-instances-by-key" rel="nofollow">Resolve instances by key</a>" section on 
  the Simple Injector website, I've played around with the suggested IRequestHandlerFactory implementations to improve the below code, but the notes such as:</p>
  
  <blockquote>
    <p>Note: The need for keyed registration can be an indication of ambiguity in the application design and a sign of a Liskov Substitution Principle violation. Take a good look if each keyed registration shouldn’t have its own unique interface, or perhaps each registration should implement its own version of a generic interface.</p>
  </blockquote>
  
  <p>and</p>
  
  <blockquote>
    <p>Note: Please remember the previous note about ambiguity in the application design. In the given example the design would probably be better of by using a generic IRequestHandler&lt;TRequest&gt; interface. This would allow the implementations to be batch registered using a single line of code, saves you from using keys, and results in a configuration the is verifiable by the container.</p>
  </blockquote>
  
  <p>have got me curious.</p>
  
  <p><strong>Q</strong>: How would an actual implementation alluded to in the note (IRequestHandler&lt;TRequest&gt;) look for my situation? I've spent a while trying to figure out what it might be but can't 
  come up with a way that works.</p>
  
  <h2>What I currently have</h2>
  
  <p>To decouple view models, I currently have a view and dialog creator that listens for messages via MVVMLight's Messenger and based on those messages will
  create the necessary Windows or dialogs requested.</p>
  
  <p>I inject an IWindowResolver which is a factory (although more of a service locator really) that simply gets the requested Window type
  using the Simple Injector factory pattern on the composition root.</p>
  
  <p>I like the RegisterViewHandler in that it's clear and in one place that it stitches the Message and the associated window and the message handler together
  rather than being spread-out within the code (eg HandleEmailPopupMessage doesn't need to know about the exact type of window to obtain and the pattern
  used by HandleEmailPopupMessage can also be made generic for simple window creation and message sending). However, I believe the IWindowResolver
  could probably be less of a locator and more done to perhaps push some of the registration into the Composition Root.</p>
  
  <p><strong>Secondary Question</strong> - Is some kind of IRequestHandler&lt;TRequest&gt; easier/more robust/useful or is simply pushing the Dictionary down to the factory level as the other examples in the Simple Injector doco give, be enough of a tidyup?</p>
  
  <pre><code>// Current IWindowResolver
  interface IWindowResolver
  {
     Window CreateWindow&lt;TWindow&gt;(TWindow windowType) where TWindow : class;
  }
  
  // Current Simple Injector IWindowResolver implementation
  [UsedImplicitly]
  private sealed class SimpleInjectorWindowFactory : IWindowFactory
  {
     private readonly Container _container;
  
     public SimpleInjectorWindowFactory(Container container)
     {
        _container = container;
     }
  
     public Window CreateWindow&lt;TWindow&gt;(TWindow windowType) where TWindow : class
     {
        return _container.GetInstance&lt;TWindow&gt;() as Window;
     }
  }
  
  public class ShowEmailPopupFormMessage
  {
     public ShowEmailPopupFormMessage()
     {
        Params = new ParamsMessage();
     }
  
     public class ParamsMessage
     {
        public string CustomerName { get; set; }
        public string EmailTo { get; set; }
     }
  
     public ParamsMessage Params { get; set; }
  }
  
  // Current ViewConstructor
  class ViewConstructor
  {
     IWindowResolver _windowResolver;
     Dictionary&lt;Type, Type&gt; _viewMap = new Dictionary&lt;Type, Type&gt;(); // Maps a message type to a particular window/view type
  
     public ViewConstructor(IWindowResolver windowResolver)
     {
        _windowResolver = windowResolver;
        RegisterViewHandler&lt;ShowEmailPopupFormMessage, EmailPopupWindow&gt;(HandleEmailPopupMessage);
     }
  
     private void RegisterViewHandler&lt;TMessage, TWindow&gt;(Action&lt;TMessage&gt; messageAction)
        where TMessage : class
        where TWindow : Window
     {
        if (_viewMap.ContainsKey(typeof(TMessage)))
        {
           throw new ArgumentException("View already registered");
        }
  
        // Store the map of Message type to Window type
        _viewMap[typeof(TMessage)] = typeof(TWindow);
  
        // Register with the message handler
        Messenger.Default.Register(this, messageAction);
     }
  
     private void HandleEmailPopupMessage(ShowEmailPopupFormMessage msg)
     {
        var frm = GetMappedWindow(msg.GetType());
  
        // We know that the View and it's associated ViewModel are now created
        // so we can send some initialization parameters to the view and or ViewModel
        Messenger.Send(msg.Params);
  
        frm.ShowDialog();
     }
  
     private Window GetMappedWindow&lt;TMessage&gt;(TMessage messageType)
     {
        var windowType = _viewMap[typeof(TMessage)];
  
        var frm = _windowResolver.CreateWindow(windowType);
  
        if (frm == null)
        {
           throw new ApplicationException("Window is not of the specified Type!");
        }
  
        // Hookup common events such as cleanup events
        frm.Unloaded += FormOnUnloaded;
  
        return frm;
     }
  
     private static void FormOnUnloaded(object sender, RoutedEventArgs eArgs)
     {
        var frm = sender as Window;
  
        if (frm == null)
        {
           return;
        }
  
        // Cleanup the ViewModel 
        var dataContext = frm.DataContext as ICleanup;
  
        if (dataContext != null)
        {
           dataContext.Cleanup();
        }
     }
  }
  
  public class EmailPopupWindow : Window
  {
     // Window knows how to set it's datacontext's ViewModel (in this case EmailPopupVm) using the ViewModelLocator declared in XML.
     // The window does not handle any messages.
  }
  
  // The View Model for the EmailPopupWindow. ViewModelBase is from MVVMLight
  public class EmailPopupVm : ViewModelBase
  {
     public EmailPopupVm()
     {
        Messenger.Register&lt;ShowEmailPopupFormMessage.ParamsMessage&gt;(HandleParamsMessage);
     }
  
     private void HandleParamsMessage(ShowEmailPopupFormMessage.ParamsMessage msg)
     {
        // Initialize the ViewModel with the parameters
        this.CustomerName = msg.CustomerName;
        this.EmailTo = msg.EmailTo;
     }
  }
  </code></pre>
  
  <p><strong>Update</strong></p>
  
  <p>For clarity, the ViewModel (now added to the example code above) actually handles the ShowEmailPopupFormMessage.ParamsMessage. The Window is oblivious to any messages.</p>