程序笔记   发布时间:2022-07-20  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了重新整理 .net core 实践篇—————Mediator实践[二十八]大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

简单整理一下R_523_11845@ediator。

正文

@H_792_2@mediator 名字是中介者的意思。

那么它和中介者模式有什么关系呢?前面整理设计模式的时候,并没有去介绍具体的中介者模式的代码实现。

如下:

https://www.cnblogs.com/aoximin/p/13600464.html

之所以没写代码就是因为它现在是一种思想,以前的简单的已经很难满足我们现在开发的需求了。

那么看下Mediator 是如何做的吧。

@H_792_2@mediator 这个服务,是如何让我们的命令查询职责分离的。

首先安装一下包:

重新整理 .net core 实践篇—————Mediator实践[二十八]

@H_792_2@mediator 核心接口为:

  1. IMediator

  2. Irequest,Irequest

  3. IrequestHandler<in Irequest,TResponse>

一般从接口就能看到其设计思想,其余的实现,各有各的想法,那么就来看下IMediator吧。

/// <sumMary>
/// Defines a mediator to encapsulate request/response and publishing interaction patterns
/// </sumMary>
public interface IMediator : ISender, IPublisher
{
}

这个接口的作用是定义了一个中介者,这个中介者用来装入请求或者响应和实现一些交互模式。

那么看来分别就是ISender和IPublisher来实现了。

看下ISender:

/// <sumMary>
/// Send a request through the mediator pipeline to be handled by a single handler.
/// </sumMary>
public interface ISender
{
	/// <sumMary>
	/// Asynchronously send a request to a single handler
	/// </sumMary>
	/// <typeparam name="TResponse">Response type</typeparam>
	/// <param name="request">request object</param>
	/// <param name="cancellationToken">Optional cancellation token</param>
	/// <returns>A task that represents the send operation. The task result contains the handler response</returns>
	Task<TResponse> Send<TResponse>(Irequest<TResponse> request, CancellationToken cancellationToken = default);

	/// <sumMary>
	/// Asynchronously send an object request to a single handler via dynamic dispatch
	/// </sumMary>
	/// <param name="request">request object</param>
	/// <param name="cancellationToken">Optional cancellation token</param>
	/// <returns>A task that represents the send operation. The task result contains the type erased handler response</returns>
	Task<object?> Send(object request, CancellationToken cancellationToken = default);
}

这个接口用来通过由单个处理程序的中介者管道中发送请求。

IPublisher:

/// <sumMary>
/// Publish a notification or event through the mediator pipeline to be handled by multiple handlers.
/// </sumMary>
public interface IPublisher
{
	/// <sumMary>
	/// Asynchronously send a notification to multiple handlers
	/// </sumMary>
	/// <param name="notification">Notification object</param>
	/// <param name="cancellationToken">Optional cancellation token</param>
	/// <returns>A task that represents the publish operation.</returns>
	Task Publish(object notification, CancellationToken cancellationToken = default);

	/// <sumMary>
	/// Asynchronously send a notification to multiple handlers
	/// </sumMary>
	/// <param name="notification">Notification object</param>
	/// <param name="cancellationToken">Optional cancellation token</param>
	/// <returns>A task that represents the publish operation.</returns>
	Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default)
		where TNotification : INotification;
}

这个接口用来通过多个处理程序的中介者管道中发送通知或者事件。

好了,现在我们得到的信息有"发布"、"事件"、"请求"、"管道" 这几个名词了。

那么实际上我们也能大致的猜出它是怎么实现的。

接下来查看Irequest:

/// <sumMary>
/// Marker interface to represent a request with a void response
/// </sumMary>
public interface Irequest : Irequest<Unit> { }

/// <sumMary>
/// Marker interface to represent a request with a response
/// </sumMary>
/// <typeparam name="TResponse">Response type</typeparam>
public interface Irequest<out TResponse> : IBaserequest { }

/// <sumMary>
/// Allows for generic type consTraints of objects implemenTing Irequest or Irequest{TResponsE}
/// </sumMary>
public interface IBaserequest { }

这些上面的英文已经提示了,标志性作用,用来做定义的。

最后来看下IrequestHandler接口:

/// <sumMary>
/// Defines a handler for a request
/// </sumMary>
/// <typeparam name="Trequest">The type of request being handled</typeparam>
/// <typeparam name="TResponse">The type of response from the handler</typeparam>
public interface IrequestHandler<in Trequest, TResponse>
	where Trequest : Irequest<TResponse>
{
	/// <sumMary>
	/// Handles a request
	/// </sumMary>
	/// <param name="request">The request</param>
	/// <param name="cancellationToken">Cancellation token</param>
	/// <returns>Response from the request</returns>
	Task<TResponse> Handle(Trequest request, CancellationToken cancellationToken);
}

现在我们在来整理一下名词:"发布"、"事件"、"请求"、"管道" 、"处理请求"

那么大概猜测大概通过接口来处理请求,然后还可以发布事件处理的。处理请求有处理请求的管道,且这个处理是单个处理程序,而处理事件是多个处理程序。

接下来操作一遍:

async static Task Main(String[] args)
{
	var services = new serviceCollection();

	services.AddMediatR(typeof(Program).Assembly);

	var serviceProvider = services.buildserviceProvider();

	var mediator = serviceProvider.Getservice<IMediator>();

	await mediator.Send(new SelfCommand{ CommandName ="zhangsan"});
}


internal class SelfCommand : Irequest<long>
{
	public String CommandName { get; set; }
}

internal class SelfCommandHandler : IrequestHandler<SelfCommand, long>
{
	public Task<long> Handle(SelfCommand request, CancellationToken cancellationToken)
	{
		Console.WriteLine($"处理 {nameof(SelfCommand)}请求:{request.CommandNamE}");
		return Task.FromResult(10L);
	}
}

重新整理 .net core 实践篇—————Mediator实践[二十八]

这里就有一个疑问了,为啥SelfCommandHandler会自动称为处理程序?我们并没有设置啊。

那么就来看一下send在干什么吧:

public Task<TResponse> Send<TResponse>(Irequest<TResponse> request, CancellationToken cancellationToken = default)
{
	if (request == null)
	{
		throw new ArgumentNullException(nameof(request));
	}

	var requestType = request.GetType();

	var handler = (requestHandlerWrapper<TResponse>)_requestHandlers.GetOrAdd(requestType,
		t => (requestHandlerBasE)Activator.CreateInstance(typeof(requestHandlerWrapperImpl<,>).MakeGenericType(requestType, typeof(TResponsE))));

	return handler.Handle(request, cancellationToken, _serviceFactory);
}

上面可以看到生成了一个handle,然后调用了Handle 方法。

然后进requestHandlerWrapperImpl 查看:

internal class requestHandlerWrapperImpl<Trequest, TResponse> : requestHandlerWrapper<TResponse>
	where Trequest : Irequest<TResponse>
{
	public override Task<object?> Handle(object request, CancellationToken cancellationToken,
		serviceFactory serviceFactory)
	{
		return Handle((Irequest<TResponse>)request, cancellationToken, serviceFactory)
			.ConTinueWith(t =>
			{
				if (t.IsFaulted)
				{
					ExceptionDispatchInfo.Capture(t.Exception.InnerException).Throw();
				}
				return (object?)t.Result;
			}, cancellationToken);
	}

	public override Task<TResponse> Handle(Irequest<TResponse> request, CancellationToken cancellationToken,
		serviceFactory serviceFactory)
	{
		Task<TResponse> Handler() => GetHandler<IrequestHandler<Trequest, TResponse>>(serviceFactory).Handle((Trequest) request, cancellationToken);

		return serviceFactory
			.GeTinstances<IPipelineBehavior<Trequest, TResponse>>()
			.Reverse()
			.Aggregate((requestHandlerDelegate<TResponse>) Handler, (next, pipelinE) => () => pipeline.Handle((Trequest)request, cancellationToken, next))();
	}
}

这里埋一个坑,因为看了一下,有很多细节的地方比如说Activator.CreateInstance的机制、一些管道细节,还设计到注册IPipelineBehavior<Trequest, TResponse>的实现类的机制,整理到该系列的细节篇中,将会比较详细的介绍。

现在只需要看Handle的ConTinueWith,如果失败的话,那么会返回一个异常,否则返回结果。

然后根据上面的,我们指定request对应的requstHandle 必须名字有如下规律:如SelfCommand,只需要SelfCommand加长一些即可,比如说SelfCommandHandler,比如说SelfCommandHandlerV2,还可以SelfCommand2都行。

但是呢,最好改好名字,后面加Handle。

同时,如果我们写两个SelfCommandHandler和SelfCommandHandlerV2,那么是否两个都会执行?不是的,只会执行一个。

internal class SelfCommandHandler2 : IrequestHandler<SelfCommand, long>
{
	public Task<long> Handle(SelfCommand request, CancellationToken cancellationToken)
	{
		Console.WriteLine($"处理 {nameof(SelfCommand)} V2请求:{request.CommandNamE}");
		return Task.FromResult(10L);
	}
}

internal class SelfCommandHandler : IrequestHandler<SelfCommand, long>
{
	public Task<long> Handle(SelfCommand request, CancellationToken cancellationToken)
	{
		Console.WriteLine($"处理 {nameof(SelfCommand)}请求:{request.CommandNamE}");
		return Task.FromResult(10L);
	}
}

比如说这样,那么会执行。

重新整理 .net core 实践篇—————Mediator实践[二十八]

也就是说会执行SelfCommandHandler2。

那么请求就算介绍完了,那么看下事件。

调用事件这样调用即可:

 await mediator.Publish(new SelfEvent { EventName = "SelfEvent" });

具体类:

internal class SelfEvent : INotification
{
	public String EventName { get; set; }
}

internal class SelfEventHandler : INotificationHandler<SelfEvent>
{
	public Task Handle(SelfEvent notification, CancellationToken cancellationToken)
	{
		Console.WriteLine($"SelfEventHandler 执行:{notification.EventNamE}");

		return Task.CompletedTask;
	}
}

internal class SelfEventHandlerV2 : INotificationHandler<SelfEvent>
{
	public Task Handle(SelfEvent notification, CancellationToken cancellationToken)
	{
		Console.WriteLine($"SelfEventHandlerV2 执行:{notification.EventNamE}");

		return Task.CompletedTask;
	}
}

效果:

重新整理 .net core 实践篇—————Mediator实践[二十八]

那么和requst不同的是,注册几个就会调用几个。

好了现在回到中介者模式中来。

中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

那么Mediator 这个模块呢,帮助我们解决了request和requesthandle之间的耦合,和 Event与EventHandle 之间的耦合。

一开始我认为是命令模式,后来一想,命令模式解决“行为请求者”与“行为实现者”的耦合。

命令模式如下:

https://www.cnblogs.com/aoximin/p/13616558.html

上面只是命令模式的一种形式哈。

下一节领域事件的处理。以上只是个人整理,如有错误,望请指点。

大佬总结

以上是大佬教程为你收集整理的重新整理 .net core 实践篇—————Mediator实践[二十八]全部内容,希望文章能够帮你解决重新整理 .net core 实践篇—————Mediator实践[二十八]所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。