Ausführung von Mediendiemedricessor nur für bestimmte Schnittstellentypen (Befehle)
Posted: 15 May 2025, 05:02
[ HINWEIS: Dies ist eine "Ersatz" -Anfrage. Der erste basierte auf dem Code meines Hauptprojekts, daher habe ich die Frage mit Code aus einem einzelnen Projekt überarbeitet, das den Prinzip sauberer veranschaulicht. Die Frage bleibt gleich, nur besser präsentiert.]
Das Szenario
Ich versuche, einen Befehlsvorverarbeitungsor auf einer CQRS-Anforderungspipeline mithilfe von Mediattr-Pipeline-Verhaltensweisen und AutoFAC für Anforderungsrouting einzurichten. Mein Ziel ist es, dass der Pre-Processor nur für Befehle (icommand ) im Gegensatz zu allen Anfragen (irequest ) ausgeführt wird. Jede Methode, mit der ich versucht habe, die Injektion zu "filtern", gibt entweder einen Fehler zurück oder führt einfach nicht den gewünschten Vorprozessor aus.
Meine Frage
Alle Ideen, wie ich einen Vorprozessor registrieren kann, der nur auf Feuer für IREquest Typen, die geschlossen sind, sind geschlossen, die geschlossen sind. /> Das gesamte minimale Beispielprojekt kann unter https://github.com/jhoiby/mediatrprocessOrtest
autofac mediTr -Konfiguration
-Anarbeitskonfiguration mit einem einzelnen Generikum -Ganze -Gattung -Gattung -Gattung -Gattung -Gattung -Gattung -Gattungstr.
MyCommandPrepresor-Klasse
Ich experimentiere mit beiden, generischen und nicht generischen:
Vererbungsstrukturen
Das Szenario
Ich versuche, einen Befehlsvorverarbeitungsor auf einer CQRS-Anforderungspipeline mithilfe von Mediattr-Pipeline-Verhaltensweisen und AutoFAC für Anforderungsrouting einzurichten. Mein Ziel ist es, dass der Pre-Processor nur für Befehle (icommand ) im Gegensatz zu allen Anfragen (irequest ) ausgeführt wird. Jede Methode, mit der ich versucht habe, die Injektion zu "filtern", gibt entweder einen Fehler zurück oder führt einfach nicht den gewünschten Vorprozessor aus.
Code: Select all
// Pipeline pre/post processors
builder
.RegisterGeneric(typeof(RequestPostProcessorBehavior))
.As(typeof(IPipelineBehavior));
builder
.RegisterGeneric(typeof(RequestPreProcessorBehavior))
.As(typeof(IPipelineBehavior));
// Works as desired: Fires generic pre-processor for ALL requests, both cmd and query
builder
.RegisterGeneric(typeof(GenericRequestPreProcessor))
.As(typeof(IRequestPreProcessor));
// Works for all requests, but I need a way to limit it to commands
builder
.RegisterGeneric(typeof(MyCommandPreProcessor))
.As(typeof(IRequestPreProcessor));
< /code>
Konzeptionell versuche ich so etwas wie eines davon zu tun, was fehlschlägt: < /p>
builder
.RegisterGeneric(typeof(MyCommandPreProcessor)) // Note generic
.As(typeof(IRequestPreProcessor));
// Intellisense error "Unexpected use of an unbound generic"
builder
.RegisterType(typeof(MyCommandPreProcessor)) // Note non-generic
.As(typeof(IRequestPreProcessor));
// Intellisense error "Unexpected use of an unbound generic"
builder
.RegisterType(typeof(MyCommandPreProcessor)) // Note non-generic
.As(typeof(IRequestPreProcessor));
// No errors, but MyCommandPreProcessor not firing
< /code>
Ich probiere ein paar verschiedene Konfigurationen für MyCommandpreprozessor, ein generisches und nicht generisches, aber mit beiden: < /p>
verblüfft.public class MyCommandPreProcessor : IRequestPreProcessor
{
public Task Process(TRequest request, CancellationToken cancellationToken)
{
Debug.WriteLine("***** MYCOMMAND PREPROCESSOR CALLED *****");
return Task.CompletedTask;
}
}
- OR -
public class MyCommandPreProcessor : IRequestPreProcessor
{
public Task Process(TRequest request, CancellationToken cancellationToken)
{
Debug.WriteLine("***** MYCOMMAND PREPROCESSOR CALLED *****");
return Task.CompletedTask;
}
}
Alle Ideen, wie ich einen Vorprozessor registrieren kann, der nur auf Feuer für IREquest Typen, die geschlossen sind, sind geschlossen, die geschlossen sind. /> Das gesamte minimale Beispielprojekt kann unter https://github.com/jhoiby/mediatrprocessOrtest
autofac mediTr -Konfiguration
-Anarbeitskonfiguration mit einem einzelnen Generikum -Ganze -Gattung -Gattung -Gattung -Gattung -Gattung -Gattung -Gattungstr.
Code: Select all
builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();
var mediatrOpenTypes = new[]
{
typeof(IRequestHandler),
typeof(IRequestHandler),
typeof(INotificationHandler)
};
foreach (var mediatrOpenType in mediatrOpenTypes)
{
// Register all command handler in the same assembly as WriteLogMessageCommandHandler
builder
.RegisterAssemblyTypes(typeof(MyCommandHandler).GetTypeInfo().Assembly)
.AsClosedTypesOf(mediatrOpenType)
.AsImplementedInterfaces();
// Register all QueryHandlers in the same assembly as GetExternalLoginQueryHandler
builder
.RegisterAssemblyTypes(typeof(MyQueryHandler).GetTypeInfo().Assembly)
.AsClosedTypesOf(mediatrOpenType)
.AsImplementedInterfaces();
}
// Pipeline pre/post processors
builder.RegisterGeneric(typeof(RequestPostProcessorBehavior)).As(typeof(IPipelineBehavior));
builder.RegisterGeneric(typeof(RequestPreProcessorBehavior)).As(typeof(IPipelineBehavior));
builder.RegisterGeneric(typeof(GenericRequestPreProcessor)).As(typeof(IRequestPreProcessor));
// builder.RegisterGeneric(typeof(GenericRequestPostProcessor)).As(typeof(IRequestPostProcessor));
// builder.RegisterGeneric(typeof(GenericPipelineBehavior)).As(typeof(IPipelineBehavior));
builder.Register(ctx =>
{
var c = ctx.Resolve();
return t => c.Resolve(t);
});
builder.Register(ctx =>
{
var c = ctx.Resolve();
return t => (IEnumerable)c.Resolve(typeof(IEnumerable).MakeGenericType(t));
});
Ich experimentiere mit beiden, generischen und nicht generischen:
Code: Select all
public class MyCommandPreProcessor : IRequestPreProcessor
{
public Task Process(TRequest request, CancellationToken cancellationToken)
{
Debug.WriteLine("***** MYCOMMAND PREPROCESSOR CALLED *****");
return Task.CompletedTask;
}
}
- AND -
public class MyCommandPreProcessor : IRequestPreProcessor
{
public Task Process(TRequest request, CancellationToken cancellationToken)
{
Debug.WriteLine("***** MYCOMMAND PREPROCESSOR CALLED *****");
return Task.CompletedTask;
}
}
Code: Select all
// Requests
IMediatR.IRequest