Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The problem is that Simple Injector will never be able to wrap an <code>ICommandHandler&lt;T&gt;</code> implementation with one of your decorators, because there is an unresolvable generic type <code>TCommand</code>. You would have noticed this if the <code>Handle</code> method of your decorators would call the <code>decorated</code> instance. For instance:</p> <pre><code>public class CreateValidFriendlyUrlCommandHandler&lt;TCommand&gt; : ICommandHandler&lt;CreateProductCommand&gt; { private readonly ICommandHandler&lt;TCommand&gt; decorated; public CreateValidFriendlyUrlCommandHandler( ICommandHandler&lt;TCommand&gt; decorated) { this.decorated = decorated; } public void Handle(CreateProductCommand command) { // This won't compile since CreateProductCommand and // TCommand are not related. this.decorated.Handle(command); } } </code></pre> <p>This code won't compile, since the decorator's <code>Handle</code> method takes an <code>CreateProductCommand</code> argument, while the <code>decorated</code> instance takes a <code>TCommand</code> argument, which isn't specified (and nowhere is stated that <code>CreateProductCommand</code> is a <code>TCommand</code>).</p> <p>In fact you didn't create a decorator at all. A decorator wraps an instance of the same interface that it implements. You wrap an <code>ICommandHandler&lt;TCommand&gt;</code> while you implement an <code>ICommandHandler&lt;CreateProductCommand&gt;</code>. The only way you would get this to work is when you explicitly specify the <code>TCommand</code> to be a <code>CreateProductCommand</code>, as follows:</p> <pre><code>ICommandHandler&lt;CreateProductCommand&gt; handler = new CreateValidFriendlyUrlCommandHandler&lt;CreateProductCommand&gt;( new CreateProductCommandHandler() ); </code></pre> <p>Still, there is no way for Simple Injector to 'guess' that this <code>TCommand</code> should be a <code>CreateProductCommand</code> and that's why your 'decorator' didn't get wrapped.</p> <p>Long story short: ditch the <code>TCommand</code>:</p> <pre><code>public class CreateValidFriendlyUrlCommandHandler : ICommandHandler&lt;CreateProductCommand&gt; { private ICommandHandler&lt;CreateProductCommand&gt; decorated; public CreateValidFriendlyUrlCommandHandler( ICommandHandler&lt;CreateProductCommand&gt; decorated) { this.decorated = decorated; } public void Handle(CreateProductCommand command) { // logic here } } </code></pre> <p>Or make it generic with a type constraint:</p> <pre><code> public class CreateValidFriendlyUrlCommandHandler&lt;TCommand&gt; : ICommandHandler&lt;TCommand&gt; where TCommand : CreateProductCommand { private ICommandHandler&lt;TCommand&gt; decorated; public CreateValidFriendlyUrlCommandHandler( ICommandHandler&lt;TCommand&gt; decorated) { this.decorated = decorated; } public void Handle(TCommand command) { // logic here } } </code></pre> <p>or remove the type constraint and allow handling any type of command, not only <code>CreateProductCommand</code>.</p> <p>Note that if you are defining many decorators that can only handle one specific type of command handler, you might want to reconsider your strategy. There might be a problem in your design.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload