Inject interface in INotificationHandler MediatR

0

I am tryin to implement some MediatR INotification in my solution. My problem is that i cant figure out how to be able to inject an interface 'ISchemaRepository' in one INotificationHandler<>. The MediatR and all classes below are in my ASP.NET Core project, and the ISchemaRepository is in a different .NET core class library, and the 'SchemaRepository' is located in a different ASP.NET Core project. Basically what i want to achive is to get data from one db and insert into another db in another project.

I have been reading alot of articles concerning the MediatR but havnt found any examples on how to achive this. Is it even possible to inject an interface into a 'INotificationHandler<>'? I know i might be in deep water and i am still a bit of a rookie when it comes to programming.

When i run the application in its following state i get an exception:

"An exception was thrown while activating λ:MediatR.INotificationHandler`1[[Facade.Application.Events.GetScheduleEvent, Facade, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]][] -> Facade.Application.Events.ScheduleEventHandler -> ServiceApi.Repository.SchemaRepository."

I tried a couple of different solutions in my ApplicationModule and MediatorModule since my guess is that this is related to dependencyinjection. My best guess was to add

            builder.RegisterType<ScheduleEventHandler>()
            .As<ISchemaRepository>()
            .InstancePerLifetimeScope();

to my 'ApplicationModule' but then i get this exception on startup:

"System.ArgumentException HResult=0x80070057 Message=The type 'Facade.Application.Events.ScheduleEventHandler' is not assignable to service 'Service.InternalResourceRepository.ISchemaRepository'. Source=Autofac StackTrace: at Autofac.Builder.RegistrationBuilder.CreateRegistration(Guid id, RegistrationData data, IInstanceActivator activator, Service[] services, IComponentRegistration target) in C:\projects\autofac\src\Autofac\Builder\RegistrationBuilder.cs:line 192 "

This is my INotificationHandler<>:

    public class ScheduleEventHandler : INotificationHandler<GetScheduleEvent>
{
    private readonly ISchemaRepository _repository;
    public ScheduleEventHandler(ISchemaRepository repository)
    {
        _repository = repository;
    }

    public Task Handle(GetScheduleEvent notification, CancellationToken cancellationToken)
    {
        _repository.SeedSchedule();

        return Task.CompletedTask;
    }
}

'GetScheduleEvent' is just an empty class declared with 'INotification'.

This is my 'MediatorModule':

    public class MediatorModule : Autofac.Module
{
    /// <summary>
    /// Implementing the Mediator
    /// </summary>
    /// <param name="builder"></param>
    protected override void Load(ContainerBuilder builder)
    {
        builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly)
            .AsImplementedInterfaces();            

        //Events
        builder.RegisterAssemblyTypes(typeof(ScheduleEventHandler).GetTypeInfo().Assembly)
            .AsClosedTypesOf(typeof(INotificationHandler<>));

        builder.Register<ServiceFactory>(context =>
        {
            var componentContext = context.Resolve<IComponentContext>();
            return t => { object o; return componentContext.TryResolve(t, out o) ? o : null; };
        });

    }
}

As you can see i am using AutoFac. This is my ApplicationModule:

   public class ApplicationModule : Autofac.Module
{

    public string QueriesConnectionString { get; }

    public ApplicationModule(string qconstr)
    {
        QueriesConnectionString = qconstr;

    }

    protected override void Load(ContainerBuilder builder)
    {

        builder.RegisterType<SchemaRepository>()
            .As<ISchemaRepository>()
            .InstancePerLifetimeScope();
    }
}

Appreciate all help i can get to solve this issue, if it can be solved.

Thank you!

c#
.net
autofac
mediator
asked on Stack Overflow Jun 19, 2019 by jagge123

1 Answer

1
builder.RegisterType<ScheduleEventHandler>()
            .As<ISchemaRepository>()
            .InstancePerLifetimeScope();

This says "When I resolve ISchemaRepository I want you to give me a new ScheduleEventHandler however:

public class ScheduleEventHandler : INotificationHandler<GetScheduleEvent>

ScheduleEventHandler doesn't implement ISchemaRepository. This isn't an Autofac thing, it's that you haven't implemented the interface.

For example, this would also fail:

var s = new ScheduleEventHandler();
var r = (ISchemaRepository)s;

You can only register types As<T> things that they implement/derive from.

If you want to troubleshoot the original exception, you need to look at the inner exception message.

An exception was thrown while activating λ:MediatR.INotificationHandler`1[[Facade.Application.Events.GetScheduleEvent, Facade, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]][] -> Facade.Application.Events.ScheduleEventHandler -> ServiceApi.Repository.SchemaRepository.

That's just the beginning. Keep reading, you should see what that exception actually was and possibly get some guidance as to how to fix it. Watch the Debug window, too, you may get some logs in there.

answered on Stack Overflow Jun 19, 2019 by Travis Illig

User contributions licensed under CC BY-SA 3.0