title: Register Open Generic Decorator with Scrutor
body: <p>I have a standard .Net core Api and want to use a Open Generic IReposistory and decorate that with a DomainEventPublisher for pushing out events to servicsBus after persisting.
  However, I have used Simple Injector a lot earlier which I'm a big fan of. But now when using MediatR Im trying to simplify DI by using just .net Core DI together with Scrutor package for decorating.</p>
  <p><strong>Problem is an error I get:
  &quot;The number of generic arguments provided doesn't equal the arity of the generic type definition.&quot; from Scrutor when trying to register decorator in Startup (2nd line below).</strong></p>
  <pre><code>services.AddSingleton(typeof(IRepository&lt;&gt;), typeof(Repository&lt;&gt;));
  services.Decorate(typeof(IRepository&lt;&gt;), typeof(DomainEventPublisher&lt;&gt;));
  </code></pre>
  <p>I have closed these generic classes/interfaces and then it works. But Im not good with that. I would to i the right way like I used to do in Simpleinjector, and register open generic decorator.</p>
  <p>Any suggestions what might be the problem?</p>
  <pre><code> public class Repository&lt;TEntity&gt; : IRepository&lt;TEntity&gt;
  {
      private readonly CosmosClient _client;
      private readonly IDataContext&lt;TEntity&gt; _context;
      private readonly Container _container;
  
      public Repository(CosmosClient client, IDataContext&lt;TEntity&gt; context)
      {
          _client = client;
          _context = context ?? throw new ArgumentNullException(nameof(context));
          _container = _client.GetContainer(_context.GetDatabase(), _context.GetContainer());
      }
  
  
      public virtual async Task Add(TEntity entity)
      {
          try
          {
              var response = await _container.CreateItemAsync(entity, new PartitionKey(_context.GetPartitionKey(entity)));
          }
          catch (Exception e)
          {
              Console.WriteLine(e);
              throw;
          }
        
      }
  
      public virtual async Task&lt;TEntity&gt; Get(string id)
      {
          var response = await _container.ReadItemAsync&lt;TEntity&gt;(id, new PartitionKey(_context.GetPartitionKey(id)));
  
          return response.Resource;
      }
  
      public virtual async Task&lt;TEntity&gt; Update(TEntity entity)
      {
          var response = await _container.UpsertItemAsync(entity, new PartitionKey(_context.GetPartitionKey(entity)));
          
          return response.Resource;
      }
  
      public async Task Remove(string id)
      {
          var response = await _container.DeleteItemAsync&lt;TEntity&gt;(id, new PartitionKey(_context.GetPartitionKey(id)));
      }
  
  public class DomainEventPublisher&lt;TEntity&gt; : IRepository&lt;TEntity&gt;
  {
      private readonly IRepository&lt;TEntity&gt; _decoratedRepository;
      private readonly ITopicAdapter _bus;
      private readonly IMapper _mapper;
  
      private List&lt;IDomainEvent&gt; _eventsToProcess = new List&lt;IDomainEvent&gt;();
  
      public DomainEventPublisher(IRepository&lt;TEntity&gt; decoratedRepository, ITopicAdapter bus, IMapper mapper)
      {
          _decoratedRepository = decoratedRepository ?? throw new ArgumentNullException(nameof(decoratedRepository));
          _bus = bus ?? throw new ArgumentNullException(nameof(bus));
          _mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
      }
      public async Task Add(TEntity entity)
      {
          // Get all domain events raised by source entity
          var events = CollectEvents(entity);
          await _decoratedRepository.Add(entity);
          await HandleEvents(events);
      }
  
      public async Task&lt;TEntity&gt; Get(string id)
      {
          return await _decoratedRepository.Get(id);
      }
  
      public async Task&lt;TEntity&gt; Update(TEntity entity)
      {
          // Get all domain events raised by source entity
          var events = CollectEvents(entity);
          var result = await _decoratedRepository.Update(entity);
          await HandleEvents(events);
  
          return result;
      }
  
      public async Task Remove(string id)
      {
          await _decoratedRepository.Remove(id);
      }
  
      private List&lt;IDomainEvent&gt; CollectEvents(TEntity entity)
      {
          if (entity is IEntity entityWithEvents)
              return entityWithEvents.Events;
  
          return new List&lt;IDomainEvent&gt;();
      }
  
      private async Task HandleEvents(List&lt;IDomainEvent&gt; events)
      {
          // if we ended up on this line we know that repository persisted changes and now send events to bus
          foreach (var domainEvent in events)
          {
              await _bus.Send(_mapper.MapTo(domainEvent));
          }
      }
  }
  </code></pre>