如何将 Mediatr 添加到 DryIoc
How to add Mediatr to DryIoc
我目前正在尝试移植 Mediatr 管道 (Mediatr 7.0.0
) 实现以使用 DryIoc
Container
(v. 4.0.5
)。我使用了 DryIoC
版本 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);
}
实现在 3.0.2
上运行良好,我的管道似乎也很好(如果我只是将 nuget 包从 4.0.5
更改为 3.0.2
,一切正常)。但是在 4.0.5
我收到异常:
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)
(删除了 Stacktrace 中某些项目的完整文件路径。但是没有 DryIoC
class 被编辑,因此行号应该是正确的)。
我尝试使用 this DryIoC
example 解决问题。
然而,这对我不起作用,因为 Container
试图让许多 Types
注册。这就是为什么我切换到这一行:
container.RegisterMany(typeof(CopyManualsHandler).GetAssembly().GetTypes().Where(t => t.IsMediatorHandler()));
它利用此方法查找所有 RequestHandlers:
public static bool IsMediatorHandler(this Type arg)
{
return arg.GetInterfaces()
.Where(i => i.Name.StartsWith("IRequestHandler"))
.Any();
}
现在的问题:我在注册类型时做错了什么吗?或者这可能是来自 DryIoc
的错误?
您正在使用 DryIoc 源代码包并同时注册其 public 类型。
您需要在 RegisterMany
调用中过滤掉 DryIoc
命名空间,或者使用 DryIoc.Internal 或 DryIoc.dll 个包。
我目前正在尝试移植 Mediatr 管道 (Mediatr 7.0.0
) 实现以使用 DryIoc
Container
(v. 4.0.5
)。我使用了 DryIoC
版本 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);
}
实现在 3.0.2
上运行良好,我的管道似乎也很好(如果我只是将 nuget 包从 4.0.5
更改为 3.0.2
,一切正常)。但是在 4.0.5
我收到异常:
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)
(删除了 Stacktrace 中某些项目的完整文件路径。但是没有 DryIoC
class 被编辑,因此行号应该是正确的)。
我尝试使用 this DryIoC
example 解决问题。
然而,这对我不起作用,因为 Container
试图让许多 Types
注册。这就是为什么我切换到这一行:
container.RegisterMany(typeof(CopyManualsHandler).GetAssembly().GetTypes().Where(t => t.IsMediatorHandler()));
它利用此方法查找所有 RequestHandlers:
public static bool IsMediatorHandler(this Type arg)
{
return arg.GetInterfaces()
.Where(i => i.Name.StartsWith("IRequestHandler"))
.Any();
}
现在的问题:我在注册类型时做错了什么吗?或者这可能是来自 DryIoc
的错误?
您正在使用 DryIoc 源代码包并同时注册其 public 类型。
您需要在 RegisterMany
调用中过滤掉 DryIoc
命名空间,或者使用 DryIoc.Internal 或 DryIoc.dll 个包。