找回密码
 立即注册
首页 业界区 业界 【EF Core】实体类的依赖注入

【EF Core】实体类的依赖注入

笃迩讦 昨天 19:09
在使用外部模型那篇水文中,有大伙伴提出:老周,你那个 Ultraman 类和 Speciality 类的的关系是不是有问题,外键不应该在 Speciality 类上吗,怎么会跑到 Ultraman 类上?因为它们是一对一关系,在配置的时候你也可以反过来,主要区别是谁引用谁的问题,由于是一对一引用,所以反过来也可以的。
今天咱们聊聊实体类构造函数的依赖注入。实体类也支持依赖注入,不过,目前版本只支持注入 EF Core 自己的服务类型,你在代码中添加的应用程序级服务类型不能注入(以后可能会支持)。总结一下,以下服务类型可以注入:
1、EF Core 框架内部注册的服务类型;
2、三个补充类型:
  a、当前 DbContext 实例(你从 DbContext 派生的类);
  b、当前实体相关的 IEntityType,可以获取实体模型相关信息;
  c、ILazyLoader 接口,延时加载时用得上。
 
现在要解决一个问题:我怎么知道 EF Core 框架内部哪些服务可以注入?这个活儿有两个方案:第一个方案是看 EF Core 源代码,在 EFCore\Infrastructure 下,注意看 EntityFrameworkServicesBuilder 类的 CoreServices 字段或 TryAddCoreServices 方法,基本齐全了。
  1.     public static readonly IDictionary<Type, ServiceCharacteristics> CoreServices
  2.         = new Dictionary<Type, ServiceCharacteristics>
  3.         {
  4.             { typeof(<strong>LoggingDefinitions</strong>), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  5.             { typeof(<strong>IDatabaseProvider</strong>), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) },
  6.             { typeof(<strong>IDbSetFinder</strong>), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  7.             { typeof(<strong>IDbSetInitializer</strong>), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  8.             { typeof(IDbSetSource), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  9.             { typeof(IEntityFinderSource), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  10.             { typeof(IStructuralTypeMaterializerSource), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  11.             { typeof(ITypeMappingSource), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  12.             { typeof(IModelCustomizer), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  13.             { typeof(IModelCacheKeyFactory), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  14.             { typeof(IModelSource), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  15.             { typeof(IModelRuntimeInitializer), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  16.             { typeof(IInternalEntrySubscriber), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  17.             { typeof(IEntityEntryGraphIterator), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  18.             { typeof(IValueGeneratorCache), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  19.             { typeof(ISingletonOptionsInitializer), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  20.             { typeof(ILoggingOptions), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  21.             { typeof(ICoreSingletonOptions), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  22.             { typeof(IModelValidator), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  23.             { typeof(ICompiledQueryCache), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  24.             { typeof(IValueConverterSelector), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  25.             { typeof(IConstructorBindingFactory), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  26.             { typeof(IRegisteredServices), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  27.             { typeof(IPropertyParameterBindingFactory), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  28.             { typeof(IParameterBindingFactories), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  29.             { typeof(IMemberClassifier), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  30.             { typeof(IMemoryCache), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  31.             { typeof(IEvaluatableExpressionFilter), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  32.             { typeof(INavigationExpansionExtensibilityHelper), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  33.             { typeof(ILiftableConstantFactory), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  34.             { typeof(IExceptionDetector), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  35.             { typeof(IJsonValueReaderWriterSource), new ServiceCharacteristics(ServiceLifetime.Singleton) },
  36.             { typeof(IProviderConventionSetBuilder), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  37.             { typeof(IConventionSetBuilder), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  38.             { typeof(IDiagnosticsLogger<>), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  39.             { typeof(IInterceptors), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  40.             { typeof(ILoggerFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  41.             { typeof(IEntityGraphAttacher), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  42.             { typeof(IKeyPropagator), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  43.             { typeof(INavigationFixer), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  44.             { typeof(ILocalViewListener), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  45.             { typeof(IStateManager), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  46.             { typeof(IConcurrencyDetector), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  47.             { typeof(IInternalEntityEntryNotifier), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  48.             { typeof(IValueGenerationManager), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  49.             { typeof(IChangeTrackerFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  50.             { typeof(IChangeDetector), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  51.             { typeof(IDbContextServices), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  52.             { typeof(IValueGeneratorSelector), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  53.             { typeof(IExecutionStrategyFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  54.             { typeof(IExecutionStrategy), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  55.             { typeof(IAsyncQueryProvider), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  56.             { typeof(IQueryCompiler), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  57.             { typeof(ICompiledQueryCacheKeyGenerator), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  58.             { typeof(IModel), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  59.             { typeof(IDesignTimeModel), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  60.             { typeof(IUpdateAdapterFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  61.             { typeof(ICurrentDbContext), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  62.             { typeof(IDbContextDependencies), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  63.             { typeof(IDatabaseFacadeDependencies), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  64.             { typeof(IDbContextOptions), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  65.             { typeof(IDatabase), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  66.             { typeof(IDatabaseCreator), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  67.             { typeof(IDbContextTransactionManager), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  68.             { typeof(IQueryContextFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  69.             { typeof(IQueryCompilationContextFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  70.             { typeof(IQueryableMethodTranslatingExpressionVisitorFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  71.             { typeof(IQueryTranslationPreprocessorFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  72.             { typeof(IQueryTranslationPostprocessorFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  73.             { typeof(IShapedQueryCompilingExpressionVisitorFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  74.             { typeof(IDbContextLogger), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  75.             { typeof(IAdHocMapper), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  76.             { typeof(ILiftableConstantProcessor), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  77.             { typeof(ILazyLoader), new ServiceCharacteristics(ServiceLifetime.Transient) },
  78.             { typeof(ILazyLoaderFactory), new ServiceCharacteristics(ServiceLifetime.Scoped) },
  79.             { typeof(IParameterBindingFactory), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) },
  80.             { typeof(ITypeMappingSourcePlugin), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) },
  81.             {
  82.                 typeof(IEvaluatableExpressionFilterPlugin),
  83.                 new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true)
  84.             },
  85.             { typeof(ISingletonOptions), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) },
  86.             { typeof(IConventionSetPlugin), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) },
  87.             { typeof(ISingletonInterceptor), new ServiceCharacteristics(ServiceLifetime.Singleton, multipleRegistrations: true) },
  88.             { typeof(IResettableService), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) },
  89.             { typeof(IInterceptor), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) },
  90.             { typeof(IInterceptorAggregator), new ServiceCharacteristics(ServiceLifetime.Scoped, multipleRegistrations: true) }
  91.         };
复制代码
这个字典的 Key 就是核心服务的类型。Relational 库和数据库提供者可能会补充一些服务,但大都多是替换服务,即接口类型是不变的。
第二个方案是通过一个叫 IRegisteredServices 的服务,它可以列出已注册服务的 Type 列表。
  1. using (var c = new DemoContext())
  2. {
  3.     <strong>IRegisteredServices regsvcs </strong><strong>= c.GetService<IRegisteredServices>
  4. ();
  5. </strong>    foreach (var sv in regsvcs.Services)
  6.     {
  7.         Console.WriteLine(sv);
  8.     }
  9.     ……
  10. }
复制代码
这样就会列出内部已注册服务的类型。
  1. Microsoft.EntityFrameworkCore.Diagnostics.LoggingDefinitions
  2. Microsoft.EntityFrameworkCore.Storage.IDatabaseProvider
  3. Microsoft.EntityFrameworkCore.ValueGeneration.IValueGeneratorCache
  4. Microsoft.EntityFrameworkCore.Storage.IRelationalTypeMappingSource
  5. Microsoft.EntityFrameworkCore.Storage.ISqlGenerationHelper
  6. Microsoft.EntityFrameworkCore.Metadata.IRelationalAnnotationProvider
  7. Microsoft.EntityFrameworkCore.Migrations.IMigrationsAnnotationProvider
  8. Microsoft.EntityFrameworkCore.Infrastructure.IModelValidator
  9. Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure.IProviderConventionSetBuilder
  10. Microsoft.EntityFrameworkCore.Update.IUpdateSqlGenerator
  11. Microsoft.EntityFrameworkCore.Query.IEvaluatableExpressionFilter
  12. Microsoft.EntityFrameworkCore.Storage.IRelationalTransactionFactory
  13. Microsoft.EntityFrameworkCore.Update.IModificationCommandBatchFactory
  14. Microsoft.EntityFrameworkCore.Update.IModificationCommandFactory
  15. Microsoft.EntityFrameworkCore.ValueGeneration.IValueGeneratorSelector
  16. Microsoft.EntityFrameworkCore.Storage.IRelationalConnection
  17. Microsoft.EntityFrameworkCore.Migrations.IMigrationsSqlGenerator
  18. Microsoft.EntityFrameworkCore.Storage.IRelationalDatabaseCreator
  19. Microsoft.EntityFrameworkCore.Migrations.IHistoryRepository
  20. Microsoft.EntityFrameworkCore.Storage.IExecutionStrategyFactory
  21. Microsoft.EntityFrameworkCore.Query.IRelationalQueryStringFactory
  22. Microsoft.EntityFrameworkCore.Query.ICompiledQueryCacheKeyGenerator
  23. Microsoft.EntityFrameworkCore.Query.IQueryCompilationContextFactory
  24. Microsoft.EntityFrameworkCore.Query.IMethodCallTranslatorProvider
  25. Microsoft.EntityFrameworkCore.Query.IAggregateMethodCallTranslatorProvider
  26. Microsoft.EntityFrameworkCore.Query.IMemberTranslatorProvider
  27. Microsoft.EntityFrameworkCore.Query.IQuerySqlGeneratorFactory
  28. Microsoft.EntityFrameworkCore.Query.IRelationalSqlTranslatingExpressionVisitorFactory
  29. Microsoft.EntityFrameworkCore.Query.ISqlExpressionFactory
  30. Microsoft.EntityFrameworkCore.Query.IQueryTranslationPostprocessorFactory
  31. Microsoft.EntityFrameworkCore.Query.IRelationalParameterBasedSqlProcessorFactory
  32. Microsoft.EntityFrameworkCore.Query.INavigationExpansionExtensibilityHelper
  33. Microsoft.EntityFrameworkCore.Query.IQueryableMethodTranslatingExpressionVisitorFactory
  34. Microsoft.EntityFrameworkCore.Storage.IExceptionDetector
  35. Microsoft.EntityFrameworkCore.Infrastructure.ISingletonOptions
  36. Microsoft.EntityFrameworkCore.SqlServer.Infrastructure.Internal.ISqlServerSingletonOptions
  37. Microsoft.EntityFrameworkCore.SqlServer.ValueGeneration.Internal.ISqlServerValueGeneratorCache
  38. Microsoft.EntityFrameworkCore.SqlServer.Update.Internal.ISqlServerUpdateSqlGenerator
  39. Microsoft.EntityFrameworkCore.SqlServer.ValueGeneration.Internal.ISqlServerSequenceValueGeneratorFactory      
  40. Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.ISqlServerConnection
  41. Microsoft.EntityFrameworkCore.Storage.IParameterNameGeneratorFactory
  42. System.Collections.Generic.IComparer`1[Microsoft.EntityFrameworkCore.Update.IReadOnlyModificationCommand]     
  43. Microsoft.EntityFrameworkCore.Migrations.IMigrationsIdGenerator
  44. Microsoft.EntityFrameworkCore.Update.Internal.IRowKeyValueFactoryFactory
  45. Microsoft.EntityFrameworkCore.Update.Internal.IRowForeignKeyValueFactoryFactory
  46. Microsoft.EntityFrameworkCore.Update.Internal.IRowIndexValueFactoryFactory
  47. Microsoft.EntityFrameworkCore.Update.Internal.IRowIdentityMapFactory
  48. Microsoft.EntityFrameworkCore.Infrastructure.IModelCustomizer
  49. Microsoft.EntityFrameworkCore.Infrastructure.IModelRuntimeInitializer
  50. Microsoft.EntityFrameworkCore.Migrations.IMigrator
  51. Microsoft.EntityFrameworkCore.Migrations.IMigrationCommandExecutor
  52. Microsoft.EntityFrameworkCore.Migrations.IMigrationsAssembly
  53. Microsoft.EntityFrameworkCore.Storage.IDatabase
  54. Microsoft.EntityFrameworkCore.Update.IBatchExecutor
  55. Microsoft.EntityFrameworkCore.Storage.IRelationalCommandBuilderFactory
  56. Microsoft.EntityFrameworkCore.Storage.IRawSqlCommandBuilder
  57. Microsoft.EntityFrameworkCore.Update.ICommandBatchPreparer
  58. Microsoft.EntityFrameworkCore.Migrations.IMigrationsModelDiffer
  59. Microsoft.EntityFrameworkCore.Storage.ITypeMappingSource
  60. Microsoft.EntityFrameworkCore.Storage.IDatabaseCreator
  61. Microsoft.EntityFrameworkCore.Storage.IDbContextTransactionManager
  62. Microsoft.EntityFrameworkCore.Query.IQueryContextFactory
  63. Microsoft.EntityFrameworkCore.Storage.Internal.INamedConnectionStringResolver
  64. Microsoft.EntityFrameworkCore.Storage.IDatabaseFacadeDependencies
  65. Microsoft.EntityFrameworkCore.Storage.IRelationalDatabaseFacadeDependencies
  66. Microsoft.EntityFrameworkCore.Diagnostics.IRelationalConnectionDiagnosticsLogger
  67. Microsoft.EntityFrameworkCore.Diagnostics.IDiagnosticsLogger`1[Microsoft.EntityFrameworkCore.DbLoggerCategory+Database+Connection]
  68. Microsoft.EntityFrameworkCore.Diagnostics.IRelationalCommandDiagnosticsLogger
  69. Microsoft.EntityFrameworkCore.Diagnostics.IDiagnosticsLogger`1[Microsoft.EntityFrameworkCore.DbLoggerCategory+Database+Command]
  70. Microsoft.EntityFrameworkCore.Diagnostics.IInterceptorAggregator
  71. Microsoft.EntityFrameworkCore.Query.IShapedQueryCompilingExpressionVisitorFactory
  72. Microsoft.EntityFrameworkCore.Query.IQueryTranslationPreprocessorFactory
  73. Microsoft.EntityFrameworkCore.Metadata.IAdHocMapper
  74. Microsoft.EntityFrameworkCore.Query.ISqlAliasManagerFactory
  75. Microsoft.EntityFrameworkCore.Query.ILiftableConstantFactory
  76. Microsoft.EntityFrameworkCore.Query.IRelationalLiftableConstantFactory
  77. Microsoft.EntityFrameworkCore.Query.ILiftableConstantProcessor
  78. Microsoft.EntityFrameworkCore.Storage.RelationalSqlGenerationHelperDependencies
  79. Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSourceDependencies
  80. Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidatorDependencies
  81. Microsoft.EntityFrameworkCore.Update.UpdateSqlGeneratorDependencies
  82. Microsoft.EntityFrameworkCore.Metadata.RelationalAnnotationProviderDependencies
  83. Microsoft.EntityFrameworkCore.Migrations.MigrationsAnnotationProviderDependencies
  84. Microsoft.EntityFrameworkCore.Storage.ParameterNameGeneratorDependencies
  85. Microsoft.EntityFrameworkCore.Storage.RelationalTransactionFactoryDependencies
  86. Microsoft.EntityFrameworkCore.Storage.RelationalCommandBuilderDependencies
  87. Microsoft.EntityFrameworkCore.Query.QuerySqlGeneratorDependencies
  88. Microsoft.EntityFrameworkCore.Query.RelationalEvaluatableExpressionFilterDependencies
  89. Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelDependencies
  90. Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelRuntimeInitializerDependencies
  91. Microsoft.EntityFrameworkCore.Query.RelationalLiftableConstantExpressionDependencies
  92. Microsoft.EntityFrameworkCore.Migrations.MigrationsSqlGeneratorDependencies
  93. Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure.RelationalConventionSetBuilderDependencies  
  94. Microsoft.EntityFrameworkCore.Update.ModificationCommandBatchFactoryDependencies
  95. Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparerDependencies
  96. Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreatorDependencies
  97. Microsoft.EntityFrameworkCore.Migrations.HistoryRepositoryDependencies
  98. Microsoft.EntityFrameworkCore.Query.RelationalCompiledQueryCacheKeyGeneratorDependencies
  99. Microsoft.EntityFrameworkCore.Query.RelationalMethodCallTranslatorProviderDependencies
  100. Microsoft.EntityFrameworkCore.Query.RelationalAggregateMethodCallTranslatorProviderDependencies
  101. Microsoft.EntityFrameworkCore.Query.RelationalMemberTranslatorProviderDependencies
  102. Microsoft.EntityFrameworkCore.Query.SqlExpressionFactoryDependencies
  103. Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitorDependencies
  104. Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitorDependencies
  105. Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitorDependencies
  106. Microsoft.EntityFrameworkCore.Query.RelationalQueryTranslationPreprocessorDependencies
  107. Microsoft.EntityFrameworkCore.Query.RelationalQueryTranslationPostprocessorDependencies
  108. Microsoft.EntityFrameworkCore.Query.RelationalParameterBasedSqlProcessorDependencies
  109. Microsoft.EntityFrameworkCore.Storage.RelationalConnectionDependencies
  110. Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseDependencies
  111. Microsoft.EntityFrameworkCore.Query.RelationalQueryContextDependencies
  112. Microsoft.EntityFrameworkCore.Query.RelationalQueryCompilationContextDependencies
  113. Microsoft.EntityFrameworkCore.Metadata.RelationalAdHocMapperDependencies
  114. Microsoft.EntityFrameworkCore.Infrastructure.IDbSetFinder
  115. Microsoft.EntityFrameworkCore.Internal.IDbSetInitializer
  116. Microsoft.EntityFrameworkCore.Internal.IDbSetSource
  117. Microsoft.EntityFrameworkCore.Internal.IEntityFinderSource
  118. Microsoft.EntityFrameworkCore.Query.IEntityMaterializerSource
  119. Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure.IConventionSetBuilder
  120. Microsoft.EntityFrameworkCore.Infrastructure.IModelCacheKeyFactory
  121. Microsoft.Extensions.Logging.ILoggerFactory
  122. Microsoft.EntityFrameworkCore.Infrastructure.IModelSource
  123. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IInternalEntityEntrySubscriber
  124. Microsoft.EntityFrameworkCore.ChangeTracking.IEntityEntryGraphIterator
  125. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IEntityGraphAttacher
  126. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IKeyPropagator
  127. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.INavigationFixer
  128. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.ILocalViewListener
  129. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IStateManager
  130. Microsoft.EntityFrameworkCore.Infrastructure.IConcurrencyDetector
  131. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IInternalEntityEntryNotifier
  132. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IValueGenerationManager
  133. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IChangeTrackerFactory
  134. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.IChangeDetector
  135. Microsoft.EntityFrameworkCore.Internal.IDbContextServices
  136. Microsoft.EntityFrameworkCore.Internal.IDbContextDependencies
  137. Microsoft.EntityFrameworkCore.Storage.IExecutionStrategy
  138. Microsoft.EntityFrameworkCore.Query.Internal.ICompiledQueryCache
  139. Microsoft.EntityFrameworkCore.Query.IAsyncQueryProvider
  140. Microsoft.EntityFrameworkCore.Query.Internal.IQueryCompiler
  141. Microsoft.EntityFrameworkCore.Internal.ISingletonOptionsInitializer
  142. Microsoft.EntityFrameworkCore.Diagnostics.IDiagnosticsLogger`1[TLoggerCategory]
  143. Microsoft.EntityFrameworkCore.Diagnostics.IInterceptors
  144. Microsoft.EntityFrameworkCore.Diagnostics.ILoggingOptions
  145. Microsoft.EntityFrameworkCore.Infrastructure.ICoreSingletonOptions
  146. Microsoft.EntityFrameworkCore.Metadata.IModel
  147. Microsoft.EntityFrameworkCore.Metadata.IDesignTimeModel
  148. Microsoft.EntityFrameworkCore.Infrastructure.ICurrentDbContext
  149. Microsoft.EntityFrameworkCore.Infrastructure.IDbContextOptions
  150. Microsoft.EntityFrameworkCore.Infrastructure.IResettableService
  151. Microsoft.EntityFrameworkCore.Storage.ValueConversion.IValueConverterSelector
  152. Microsoft.EntityFrameworkCore.Metadata.IConstructorBindingFactory
  153. Microsoft.EntityFrameworkCore.Infrastructure.Internal.ILazyLoaderFactory
  154. Microsoft.EntityFrameworkCore.Infrastructure.ILazyLoader
  155. Microsoft.EntityFrameworkCore.Metadata.IParameterBindingFactories
  156. Microsoft.EntityFrameworkCore.Metadata.Internal.IMemberClassifier
  157. Microsoft.EntityFrameworkCore.Metadata.IPropertyParameterBindingFactory
  158. Microsoft.EntityFrameworkCore.Metadata.IParameterBindingFactory
  159. Microsoft.Extensions.Caching.Memory.IMemoryCache
  160. Microsoft.EntityFrameworkCore.Update.IUpdateAdapterFactory
  161. Microsoft.EntityFrameworkCore.Storage.Json.IJsonValueReaderWriterSource
  162. Microsoft.EntityFrameworkCore.Diagnostics.IDbContextLogger
  163. System.Diagnostics.DiagnosticSource
  164. Microsoft.EntityFrameworkCore.Metadata.LazyLoaderParameterBindingFactoryDependencies
  165. Microsoft.EntityFrameworkCore.Storage.DatabaseProviderDependencies
  166. Microsoft.EntityFrameworkCore.Infrastructure.ModelSourceDependencies
  167. Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorCacheDependencies
  168. Microsoft.EntityFrameworkCore.Infrastructure.ModelValidatorDependencies
  169. Microsoft.EntityFrameworkCore.Storage.TypeMappingSourceDependencies
  170. Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizerDependencies
  171. Microsoft.EntityFrameworkCore.Infrastructure.ModelCacheKeyFactoryDependencies
  172. Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverterSelectorDependencies
  173. Microsoft.EntityFrameworkCore.Query.Internal.EntityMaterializerSourceDependencies
  174. Microsoft.EntityFrameworkCore.Query.EvaluatableExpressionFilterDependencies
  175. Microsoft.EntityFrameworkCore.Infrastructure.RuntimeModelDependencies
  176. Microsoft.EntityFrameworkCore.Infrastructure.ModelRuntimeInitializerDependencies
  177. Microsoft.EntityFrameworkCore.Query.NavigationExpansionExtensibilityHelperDependencies
  178. Microsoft.EntityFrameworkCore.Storage.Json.JsonValueReaderWriterSourceDependencies
  179. Microsoft.EntityFrameworkCore.Query.LiftableConstantExpressionDependencies
  180. Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure.ProviderConventionSetBuilderDependencies   
  181. Microsoft.EntityFrameworkCore.Query.QueryCompilationContextDependencies
  182. Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManagerDependencies
  183. Microsoft.EntityFrameworkCore.Storage.ExecutionStrategyDependencies
  184. Microsoft.EntityFrameworkCore.Query.CompiledQueryCacheKeyGeneratorDependencies
  185. Microsoft.EntityFrameworkCore.Query.QueryContextDependencies
  186. Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitorDependencies
  187. Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessorDependencies
  188. Microsoft.EntityFrameworkCore.Query.QueryTranslationPostprocessorDependencies
  189. Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitorDependencies
  190. Microsoft.EntityFrameworkCore.ValueGeneration.ValueGeneratorSelectorDependencies
  191. Microsoft.EntityFrameworkCore.Storage.DatabaseDependencies
  192. Microsoft.EntityFrameworkCore.Infrastructure.ModelDependencies
  193. Microsoft.EntityFrameworkCore.ModelCreationDependencies
  194. Microsoft.EntityFrameworkCore.Metadata.AdHocMapperDependencies
复制代码
严重注意:实体构造函数不能注入 IRegisteredServices  类型的服务,因为 EF Core 内部实现时,本身就是从 IRegisteredServices.Services 集合中查找可以注入的服务的,而 IRegisteredServices.Services 是不包含它自己的。说人话就是:用 IRegisteredServices 类注入是找不到该服务的。
 
然后解决第二个问题:在实体类的构造函数中注入服务有啥用?大多数时候没啥用,但当你要使用某些服务来获取特殊信息,或执行特殊操作(如在实体类中执行 SQL 语句)时就用得上。
咱们举个例子,就用官方文档最喜欢的 Blog 和 Post 实体来演示。其中,Blog 类的构造函数将注入 IEntityType 服务。然后可以利用这个服务来获取 Blog 实体有几个属性,有几个键,有几个导航属性。
  1. public class Blog
  2. {
  3.     // 私有字段
  4.     private <strong>IEntityType? _thisEntity;
  5. </strong>    // 私有构造器
  6.     private Blog(IEntityType t) => _thisEntity = t;
  7.     // 公共构造器
  8.     public Blog()
  9.     {
  10.     }
  11.     public int BlogID { get; set; }
  12.     public string DisplayName { get; set; } = string.Empty;
  13.     public string Url { get; set; } = string.Empty;
  14.     public List<Post> PostList { get; set; } = new();
  15.     // 以下属性通过注入的 IEntityType 获取相关值
  16.     public int PropertyCount => _thisEntity?.GetProperties().Count() ?? 0;
  17.     public int NavigationCount => _thisEntity?.GetNavigations().Count() ?? 0;
  18.     public int KeyCount => _thisEntity?.GetKeys().Count() ?? 0;
  19. }
  20. public class Post
  21. {
  22.     public int PostID { get; set; }
  23.     public string Header { get; set; } = string.Empty;
  24.     public Blog? TheBlog { get; set; }
  25. }
复制代码
注意,你自己 new 一个 Blog 实例是没有注入功能的,所以要定义一个无参数的公共构造函数,以供外部初始化用。另一个私有构造函数有一个 IEntityType 类型的参数,可以接收注入。因为这构造函数只由 EF Core 内部调用,代码中调用无法注入,故声明为私有即可。EF Core 在查找构造函数时,不管你是公有的还是私有的,只要不是静态的,一律能发现。
在访问 Blog 实体时就可以获取键、属性、导航属性的数量。
  1. var q = c.Blogs.Include(b => b.PostList).ToArray();
  2. var first = q.FirstOrDefault();
  3. if (first != null)
  4. {
  5.     Console.WriteLine($"实体{first.GetType().Name}有{first.
  6. PropertyCount}个属性,{first.KeyCount}个键,{first.
  7. NavigationCount}个导航属性");
  8. }
复制代码
得到的输出如下:
  1. 实体Blog有3个属性,1个键,1个导航属性
复制代码
 
除了构造函数,也可以从属性注入。例如
  1. [PrimaryKey(nameof(Screen.ScrID))]
  2. public class Screen
  3. {
  4.     [Column("scr_id")]
  5.     public int ScrID { get; set; }
  6.     [Column("width")]
  7.     public int Width { get; set; }
  8.     [Column("height")]
  9.     public int Height { get; set; }
  10.     //----------- 注意以下属性 --------------
  11.     public <strong>MyDBContext? ThisContext</strong> { get; set; }
  12. }
  13. public class MyDBContext : DbContext
  14. {
  15.     public MyDBContext(DbContextOptions<MyDBContext> options)
  16.         : base(options)
  17.     { }
  18.         
  19.     public DbSet<Screen> Screens { get; set; }
  20. }
复制代码
上面示例中,MyDBContext 实例会注入到每个 Screen 实例的 ThisContext 属性。即每个实体实例的 ThisContext 属性都引用同一个 MyDBContext 对象。
  1. var q = dc.Screens.FirstOrDefault();
  2. if (q != null)
  3. {
  4.     if (q.ThisContext != null)
  5.     {
  6.         Console.WriteLine("ThisContext属性:{0}", q.ThisContext);
  7.     }
  8. }
  9. // 输出:
  10. // ThisContext属性:MyDBContext
复制代码
好了,今天就水到这里了。因为这个主题确实太简单了,老周也不必举太多例子。
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册