How to add Mediatr to DryIoc

1

I am currently trying to port a Mediatr Pipeline (Mediatr 7.0.0) implementation to use a DryIoc Container (v. 4.0.5). I Used the following implementation I had from DryIoC version 3.0.2:

private static void ConfigureMediatr(this Container container)
{
    container.RegisterDelegate<ServiceFactory>(r => r.Resolve);
    container.RegisterMany(new[] { typeof(IMediator).GetAssembly()}, Registrator.Interfaces);
    container.RegisterMany(typeof(CopyManualsHandler).GetAssembly().GetTypes().Where(t => t.IsMediatorHandler())); //Use this to only Get Mediator Handlers.

    container.Register(typeof(IPipelineBehavior<,>), typeof(RequestPreProcessorBehavior<,>), ifAlreadyRegistered: IfAlreadyRegistered.AppendNewImplementation);
    container.Register(typeof(IPipelineBehavior<,>), typeof(RequestPostProcessorBehavior<,>), ifAlreadyRegistered: IfAlreadyRegistered.AppendNewImplementation);
} 

The implementation works on 3.0.2 fine and my pipeline seems fine as well (if I just change the nuget package from 4.0.5 to 3.0.2 everything works fine). However on 4.0.5 I receive the exception:

System.TypeInitializationException
  HResult=0x80131534
  Message=The type initializer for 'DryIoc.OpenGenericTypeKey' threw an exception.
  Source=Program.Manuals
  StackTrace:
   at DryIoc.OpenGenericTypeKey..ctor(Type requiredServiceType, Object serviceKey) in Container.cs:line 2255
   at DryIoc.WrappersSupport.<>c__DisplayClass12_0.<GetArrayExpression>b__6(KV`2 f) in Container.cs:line 3656
   at ImTools.ArrayTools.Map[T,R](T[] source, Func`2 map) in ImTools.cs:line 569
   at ImTools.ArrayTools.Map[T,R](IEnumerable`1 source, Func`2 map) in ImTools.cs:line 605
   at DryIoc.WrappersSupport.GetArrayExpression(Request request) in Container.cs:line 3655
   at DryIoc.ExpressionFactory.CreateExpressionOrDefault(Request request) in Container.cs:line 9062
   at DryIoc.Factory.GetExpressionOrDefault(Request request) in Container.cs:line 7865
   at DryIoc.Container.ResolveAndCacheFactoryDelegate(Type serviceType, IfUnresolved ifUnresolved) in Container.cs:line 269
   at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, IfUnresolved ifUnresolved) in Container.cs:line 230
   at DryIoc.Resolver.Resolve(IResolver resolver, Type serviceType) in Container.cs:line 5880
   at MediatR.ServiceFactoryExtensions.GetInstances[T](ServiceFactory factory)
   at MediatR.Internal.RequestHandlerWrapperImpl`2.Handle(IRequest`1 request, CancellationToken cancellationToken, ServiceFactory serviceFactory)
   at MediatR.Mediator.Send[TResponse](IRequest`1 request, CancellationToken cancellationToken)
   at GOM.PCMF.Manuals.ViewModels.ButtonViewModel.<Copy>d__20.MoveNext() in ButtonViewModel.cs:line 76
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_0(Object state) in f:\dd\ndp\clr\src\BCL\system\runtime\compilerservices\AsyncMethodBuilder.cs:line 1018
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) in f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs:line 954
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) in f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs:line 901
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) in f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs:line 890
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at Program.Manuals.App.Main()

Inner Exception 1:
ContainerException: Unable to find a single constructor in Type OpenGenericTypeKey (including non-public=False)

(Removed the Full Filepath to some Items in the Stacktrace. However no DryIoC class was edited therefore the line numbers should be correct).

I tried to fix the issue using this DryIoC example. However this won't work for me because the Container tries to get to many Types registered. Thats why I switched to this line: container.RegisterMany(typeof(CopyManualsHandler).GetAssembly().GetTypes().Where(t => t.IsMediatorHandler()));

which utilizes this Method to find all RequestHandlers:

public static bool IsMediatorHandler(this Type arg)
        {
            return arg.GetInterfaces()
                .Where(i => i.Name.StartsWith("IRequestHandler"))
                .Any();
        }

The Question now: Am I doing something wrong while registering the types? Or could this be a bug coming from DryIoc?

c#
mediatr
dryioc
asked on Stack Overflow Aug 2, 2019 by Brezelmann • edited Aug 2, 2019 by Alex

1 Answer

1

You are using the DryIoc source package and registering its public types as well.

You need to either filter out DryIoc namespace in RegisterMany calls, or use DryIoc.Internal or DryIoc.dll packages.

answered on Stack Overflow Aug 5, 2019 by dadhi

User contributions licensed under CC BY-SA 3.0