// Composition Root - 组合根: // 设计模式。在程序的入口处进行抽象-具体的依赖关系配置。 // Pure DI public static void Main() { // 出创世区块:通过执行一批交易来初始化整条链,一般包括部署系统合约,如共识合约,多资产合约等,并对系统合约做初步配置 // 准备交易 var transactionPool = new TransactionPool { Logger = new ConsoleLogger() }; foreach (var genesisTransaction in TransactionGenerationHelper.GetGenesisTransactions()) { transactionPool.AddTransaction(genesisTransaction); } // 打包创世区块 // 准备MineService var blockValidationService = new BlockValidationService(new List <IBlockValidationProvider> { new BlockTransactionValidationProvider { Logger = new ConsoleLogger() }, new BlockBasicInformationValidationProvider { Logger = new ConsoleLogger() } }) { Logger = new ConsoleLogger() }; var blockChainService = new BlockChainService(new PureDIChainIdProvider(), blockValidationService) { Logger = new ConsoleLogger() }; var transactionExecutingService = new TransactionExecutingService { Logger = new ConsoleLogger() }; var mineService = new MineService(transactionPool, blockChainService, transactionExecutingService); // 生产创世区块 var genesisBlock = mineService.Mine(); // 把创世区块添加到链上 blockChainService.AppendBlock(genesisBlock); // 创世区块不广播,每一个节点都独立生成创世区块 // 所以NetworkService实例较晚才出现 var networkService = new NetworkService { Logger = new ConsoleLogger() }; // 开始产生其他区块 - 挖矿 // Demo: 出2个块 var count = 2; while (count > 0) { // 交易应该是从网络收取的,这里随机生成一些 var txs = TransactionGenerationHelper.GetSomeRandomTransactions(); // 正常流程:从网络中收到交易,验证交易,然后丢进交易池 foreach (var tx in txs) { transactionPool.AddTransaction(tx); } // 交易池里已经有交易了,然后开始出块 var block = mineService.Mine(); // 拿到区块以后,自己做一些列验证,没问题的话就广播,并添加到本地的链上 networkService.BroadcastBlock(block); blockChainService.AppendBlock(block); count--; } // 实际上,共识决定了谁应该在什么时候出块,以及收到一个区块以后该怎么验证这个区块的合法性 }
public static void Main() { // MS.DI中,DI容器的生成分为两步: // 先初始化ServiceCollection,进行一系列注册 // 再通过ServiceCollection生成 var serviceCollection = new ServiceCollection(); // 配置依赖关系 serviceCollection.AddSingleton <IBlockChainService, BlockChainService>(); serviceCollection.AddSingleton <ITransactionPool, TransactionPool>(); serviceCollection.AddTransient <IMineService, MineService>(); serviceCollection.AddTransient <ITransactionExecutingService, TransactionExecutingService>(); serviceCollection.AddTransient <INetworkService, NetworkService>(); serviceCollection.AddTransient <ConsoleLoggerWithTimestamp>(); serviceCollection.AddTransient <ILogger, ConsoleLoggerWithTimestampDecorator>(); serviceCollection.AddTransient <IChainIdProvider, MSDIChainIdProvider>(); serviceCollection.AddTransient <IBlockValidationService, BlockValidationService>(); // 有新的验证逻辑的时候,添加一个IBlockValidationProvider的实现,在这里添加依赖关系就行了 serviceCollection.AddSingleton <IBlockValidationProvider, BlockTransactionValidationProvider>(); serviceCollection.AddSingleton <IBlockValidationProvider, BlockBasicInformationValidationProvider>(); var container = serviceCollection.BuildServiceProvider(); // 组合根结束 // 配置Logger var loggingTypes = from type in typeof(IBlockChainService).Assembly.GetTypes() where !type.IsInterface where type.GetProperties().Any(p => p.PropertyType == typeof(ILogger)) select type; var logger = container.GetRequiredService <ILogger>(); foreach (var loggingType in loggingTypes.ToList()) { // 看起来"Logger"像是hard code过来的,但是也可以给这种方式起一个好听一点的名字: // Convention over configuration,惯例优先原则。 var loggerProperty = loggingType.GetProperty("Logger"); var targetInstance = container.GetServices(loggingType.GetInterfaces().First()) .First(i => i.GetType() == loggingType); loggerProperty?.SetValue(targetInstance, logger); } using (var scope = container.CreateScope()) { // 从scope中根据依赖获取实例 var serviceProvider = scope.ServiceProvider; var transactionPool = serviceProvider.GetRequiredService <ITransactionPool>(); var blockChainService = serviceProvider.GetRequiredService <IBlockChainService>(); var mineService = serviceProvider.GetRequiredService <IMineService>(); var transactionExecutingService = serviceProvider.GetRequiredService <ITransactionExecutingService>(); // 这里没有用 var networkService = serviceProvider.GetRequiredService <INetworkService>(); // 开始了 // 准备创世交易 foreach (var genesisTx in TransactionGenerationHelper.GetGenesisTransactions()) { transactionPool.AddTransaction(genesisTx); } // 打包添加创世区块 var genesisBlock = mineService.Mine(); blockChainService.AppendBlock(genesisBlock); // 打包其他区块 var count = 10; while (count > 0) { var txs = TransactionGenerationHelper.GetSomeRandomTransactions(); foreach (var tx in txs) { transactionPool.AddTransaction(tx); } var block = mineService.Mine(); blockChainService.AppendBlock(block); networkService.BroadcastBlock(block); count--; } } }