Silky微服务框架之服务引擎( 二 )

接口的类,并通过反射的方式构建实现类的对象,然后可以通过IServiceCollection对服务进行注册;以及通过遍历所有的Silky模块实例,通过模块的提供的ConfigureServices()的方法通过IServiceCollection对服务进行注册 。
如下代码为服务引擎提供的ConfigureServices()方法源码:
// SilkyEngine 实现的ConfigureServices注册服务的方法public void ConfigureServices(IServiceCollection services, IConfiguration configuration,IHostEnvironment hostEnvironment){_typeFinder = new SilkyAppTypeFinder(); // 创建类型查找器ServiceProvider = services.BuildServiceProvider();Configuration = configuration;HostEnvironment = hostEnvironment;HostName = Assembly.GetEntryAssembly()?.GetName().Name;// 解析应用服务主机名称var configureServices = _typeFinder.FindClassesOfType<IConfigureService>(); // 通过查找器查找所有的`IConfigureService`实现类var instances = configureServices.Select(configureService => (IConfigureService)Activator.CreateInstance(configureService));// 通过反射的方式创建`IConfigureService`实现类的实例foreach (var instance in instances) // 遍历`IConfigureService`的实现类的实例,并通过其实例实现通过IServiceCollection对服务的注册instance.ConfigureServices(services, configuration);// configure modulesforeach (var module in Modules) // 遍历各个模块,通过各个模块提供`ConfigureServices`实现服务的注册module.Instance.ConfigureServices(services, configuration);AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;}在上述代码中,我们可以看到在该方法体内主要完成如下工作:
A) 创建类型查找器、构建服务提供者以及为配置器、主机环境变量、主机名等赋值;
B) 使用类型查找器查找到所有IConfigureService实现类,并通过反射的方式创建其实例,遍历其实例,其实例通过IServiceCollection实现对服务的注册;
C) 遍历所有的模块,通过模块的实例提供的ConfigureServices()方法,通过IServiceCollection实现对服务的注册;
2.2 在上一章注册silky微服务应用中有指出, 执行ContainerBuilder方法时,主要通过AutofacContainerBuilder实现服务的依赖注册 。
public static IHostBuilder RegisterSilkyServices<T>(this IHostBuilder builder)where T : StartUpModule{// 其他代码略...builder.UseServiceProviderFactory(new AutofacServiceProviderFactory()) // 替换服务提供者工作类.ConfigureContainer<ContainerBuilder>(builder => // 通过ContainerBuilder实现服务依赖注册{engine.RegisterModules(services, builder);engine.RegisterDependencies(builder);})}我们看到,如何通过ContainerBuilder实现服务注册,也是通过服务引擎巧妙的实现:一种方式是通过模块,另外一种方式是通过约定的依赖方式 。
2.2.1 通过模块注册服务
SilkyModule的定义中,我们看到模块的基类是Autofac.Module,我们在遍历所有的模块实例的过程中,通过ContainerBuilder提供的RegisterModule()方法实现模块指定的服务的注册 。换句话说,就是在在执行RegisterModule()的方法过程中,Autofac会调用模块的提供的RegisterServices(ContainerBuilder builder)实现具体的服务注册 。
public void RegisterModules(IServiceCollection services, ContainerBuilder containerBuilder){containerBuilder.RegisterInstance(this).As<IModuleContainer>().SingleInstance();var assemblyNames = ((AppDomainTypeFinder)_typeFinder).AssemblyNames;foreach (var module in Modules){if (!assemblyNames.Contains(module.Assembly.FullName)){((AppDomainTypeFinder)_typeFinder).AssemblyNames.Add(module.Assembly.FullName);}containerBuilder.RegisterModule((SilkyModule)module.Instance);}}所以在Silky模块的定义SilkyModule中,提供了如下虚方法(RegisterServices),实际上是Autofac的基类Autofac.Module的一个基础方法,在调用containerBuilder.RegisterModule((SilkyModule)module.Instance)时 , 底层会通过调用模块的Load()实现模块的具体服务的注册 。在Load()方法中,每个模块会调用RegisterServices(builder)实现通过ContainerBuilder对服务进行注册 。
protected override void Load([NotNull] ContainerBuilder builder){base.Load(builder);RegisterServices(builder);}所以,Silky具体的模块可以通过重写RegisterServices([NotNull] ContainerBuilder builder)实现该模块使用ContainerBuilder实现服务的依赖注册 。
protected virtual void RegisterServices([NotNull] ContainerBuilder builder){}

提示使用

推荐阅读