一.写扩展方法的最小可见原则

当软件工程分多个项目构建时,互相之间会有项目引用关系。当需要扩展某类型时,应该注意这些扩展方法具体会使用在哪个项目中,从而将扩展类写在那个使用的项目中,这样达到最小范围可见的目标,从而避免扩展方法随处可见 尤其是在不需要的项目中也可见就很不好。
类似似子在C#类库中Array,List这些类型,默认只有简单的集合操作方法,如果想要引入排序、比较、筛选、分组等功能,只需要引入System.Linq命名空间即可开箱使用,这就是一个很好的示例。
以下是一个更详细的示例说明:

//项目1
var dto = new Dto{Id=1,Name="lily"};
//如果此处要使用MyServece中的Enqueue方法,则需要
var service = new MyService();
service.HandleKeyValuePair(dto.Id,dto.Name,dto.TimeSpan)

//项目2
public class MyService
{
	public void HandleKeyValuePair(int key, string value, TimeSpan span){...}
}

//项目3
public class Dto
{
	public int Id{get;set;}
	public string Name{get;set;}
	public bool Flag{get;set;}
	public TimeSpan{get;set;}
}

以上项目1引用项目2和项目3,项目2可能是解决方案中某个公用的基础中间件或说类库。可以看到service.HandleKeyValuePair(dto.Id,dto.Name,dto.TimeSpan)如果属性很多,则会写很多冗长重复的代码。
这时,为了更友好的工程构建,或者说也算是一种设计模式,则可以为项目1创建一个扩展方法以减小冗余同时增加让更多地方可以使用这种便利能用性。
如下:

//项目1
var dto = new Dto{Id=1,Name="lily"};
//如果此处要使用MyServece中的Enqueue方法,则需要
var service = new MyService();
//扩展和重构后,可以使用以下很简洁的写法了
service.HandleKeyValuePair(dto);

//在项目1中扩展MyService类的功能
static class MyServiceExtensions
{
	static void HandleKeyValuePair(this MyService service, Dto dto, string reMarks = "")
	{
		service.HandleKeyValuePair(dto.Id,dto.Name,dto.TimeSpan);
	}
}

注意脑回路:以上,我们一开始可能想在MyService写一个扩展方法,用来扩展Dto的功能,但考虑到该扩展方法可只在项目1中使用,也可能项目2为一个第三方库不允许被改动,所以,不论是考虑到尽量不污染现有工程代码还是可行性方法,我们都应该改为在项目1中增加扩展方法来扩展MyService的功能。

二.将一些诸如依赖注入注册自身服务的扩展方法封装在基础类库自身项目中,从而使得高层引用者可以调用这些方法轻松注册基础类库项目中的类型。

具体的做法:
2.1.在基础类库项目中引用Microsoft.Extensions.DependencyInjection.Abstractions,主要是为了引用未实现的 IServiceCollection 中的接口方法。
2.2.在基础类库项目中注册自己的一些服务,以供高层调用者调用,比如:

//假如类库项目名称叫CustomServices,则我们可以写一个或一些扩展方法
public static class CustomServiceExtensions
{
	public IServiceCollection AddCustomServices(this IServiceCollection services)//注意是对 IServiceCollection 的扩展
	{
		services.Addsingleton<IMyLogger,MyLogger>();
		services.AddSingleton<IMySpecialTimer,MySpecialTimer>();
		services.AddTransient<IMyCustomService, MyCustomService>();
		return services;
	}
}

2.3.调用者就可以像asp.net core中一样,使用类库的AddCustomServices方法注册其所有的类型和服务。

varserviceCollection=newServiceCollection();
serviceCollection.AddcustomServices();
posted on 2025-06-03 18:35  hrx521  阅读(22)  评论(0)    收藏  举报