0

I want to register a mediator Im using from github, which provides a sample for registering it using Autofac.

I think my problem lies with this Autofac line:

builder.RegisterAssemblyTypes(assembly)
    .AsClosedTypesOf(typeof(IMessageHandler<,>))
    .AsImplementedInterfaces();

I'm not 100% sure what the line of code does,AsClosedTypesOf to be more specific.

I tried to translate it to DryIoc as:

container.RegisterMany(
    new Type[] { typeof(IMessageHandler<,>) },
    serviceTypeCondition: s => s.IsInterface, 
    setup: Setup.With(openResolutionScope: true));

But I get the following error:

DryIoc.ContainerException: 'Registering abstract implementation type SimpleMediator.Core.IMessageHandler<,> when it is should be concrete. Also there is not FactoryMethod to use instead.'

This is my registration code so far:

        container.RegisterMany(
            new Type[] { typeof(IMessageHandler<,>) },
            serviceTypeCondition: s => s.IsInterface, 
            setup: Setup.With(openResolutionScope: true));

        //var assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic);
        container.RegisterDelegate<ServiceFactoryDelegate>(c => t =>
        {
            return c.Resolve(t);
        });

        container.RegisterMany<ServiceFactory>();
        container.RegisterMany<Mediator>();
        container.RegisterMany(new Type[] { typeof(MessageProcessor<,>) });

        container.Register<IService1, Service1>(Reuse.Singleton);
        container.Register<IService2, Service2>(Reuse.Singleton);

        var service1 = container.Resolve<IService1>();
        var service2 = container.Resolve<IService2>();

        service1.GetDevice("asdf");

Without using RegisterMany for the IMessageHandler interface the program encounters the error:

System.ArgumentException: 'No handler of signature IMessageHandler`2 was found for DeviceEventMessage Arg_ParamName_Name'

Basically what I understand is that I need to register the message handlers I have defined, which inherit from IMessageHandler<,>

Mediator defines IMessageHandler as such:

public interface IEventHandler<in TEvent>
    : IMessageHandler<TEvent, Unit> where TEvent : IMessage<Unit>
{
}

And I implement it in the service:

public class Service2 : IService2, IEventHandler<DeviceEventMessage>
{
    public async Task<Unit> HandleAsync(
        DeviceEventMessage message,
        IMediationContext mediationContext,
        CancellationToken cancellationToken)
    {
        return Unit.Result;
    }
}

Where service1 actually calls the mediator in GetDevice("asdf") which requires the handler to be resolved.

How would I register classes implementing IMessageHandler<,> in DryIoc?

Steven
  • 166,672
  • 24
  • 332
  • 435
FinalFortune
  • 635
  • 10
  • 25
  • 1
    Btw, did you now about DryIoc.Messages namespace https://www.fuget.org/packages/DryIoc.dll/4.0.5/lib/netstandard2.0/DryIoc.dll/DryIoc.Messages – dadhi Jul 22 '19 at 11:03
  • There is also a DryIoc.Syntax.Autofac.dll package: https://www.fuget.org/packages/DryIoc.Syntax.Autofac.dll – dadhi Jul 22 '19 at 11:05
  • @dadhi I did not know about the messages namespace, new to using a mediator and services so tried using one from a learning perspective. I may drop it for the DryIoc one. – FinalFortune Jul 22 '19 at 11:29

1 Answers1

3

Update: fixed the working sample

Added s.GetGenericDefinitionOrNull() in serviceTypeCondition

Answer

The exception is exactly about the problem here:

container.RegisterMany(
    new Type[] { typeof(IMessageHandler<,>) },
    serviceTypeCondition: s => s.IsInterface,
    setup: Setup.With(openResolutionScope: true));

This RegisterMany overload expects the first argument to be a collection of concrete Implementation types.

For your case you probably need something like this instead:

container.RegisterMany(
    new[] { typeof(Service1).GetAssembly() },
    serviceTypeCondition: s => s.GetGenericDefinitionOrNull() == typeof(IMessageHandler<,>));

Btw, not sure what is the reason for openResolutionScope: true.

dadhi
  • 4,807
  • 19
  • 25
  • Can't remember why I added openResolutionScope: true, wrote it in a rush. changed the line to this and the new [error](https://pastebin.com/WVWUg1Jd) – FinalFortune Jul 22 '19 at 11:24
  • I have fixed the sample - check the update and the working sample. Here is the live code sample for reference: https://dotnetfiddle.net/lM6npy – dadhi Jul 22 '19 at 15:15