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){}

提示使用

推薦閱讀