使用 DryIoc 替换 Abp 的 DI 框架 (8)

该错误在 AbpEntityFrameworkCoreModule 模块的 Initialize() 方法里面,一样的是因为使用了 IWndsorContainer 的注册方法导致的。

public override void Initialize() { IocManager.RegisterAssemblyByConvention(typeof(AbpEntityFrameworkCoreModule).Assembly); // IocManager.IocContainer.Register( // Component.For(typeof(IDbContextProvider<>)) // .ImplementedBy(typeof(UnitOfWorkDbContextProvider<>)) // .LifestyleTransient() // ); IocManager.IocContainer.Register(typeof(IDbContextProvider<>),typeof(UnitOfWorkDbContextProvider<>),Reuse.Transient); RegisterGenericRepositoriesAndMatchDbContexes(); }

而另一处错误则是在 RegisterGenericRepositoriesAndMatchDbContexes() 方法内部:

private void RegisterGenericRepositoriesAndMatchDbContexes() { // ... 其他的代码 using (IScopedIocResolver scope = IocManager.CreateScope()) { foreach (var dbContextType in dbContextTypes) { Logger.Debug("Registering DbContext: " + dbContextType.AssemblyQualifiedName); scope.Resolve<IEfGenericRepositoryRegistrar>().RegisterForDbContext(dbContextType, IocManager, EfCoreAutoRepositoryTypes.Default); // IocManager.IocContainer.Register( // Component.For<ISecondaryOrmRegistrar>() // .Named(Guid.NewGuid().ToString("N")) // .Instance(new EfCoreBasedSecondaryOrmRegistrar(dbContextType, scope.Resolve<IDbContextEntityFinder>())) // .LifestyleTransient() // ); IocManager.IocContainer.UseInstance<ISecondaryOrmRegistrar>(new EfCoreBasedSecondaryOrmRegistrar(dbContextType, scope.Resolve<IDbContextEntityFinder>())); } scope.Resolve<IDbContextTypeMatcher>().Populate(dbContextTypes); } } 4.2.4 DbContext 解析器变更

这个解析器的主要问题则与前面的不一样,这里报错是因为在构造 DbContext 的时候需要传入构造参数。根据我们之前的改动,现在 Resolve() 方法传入的是一个 object[] 数组,而不是原来的 object 对象,所以这里需要进行一些细微的改动。

using Abp.Dependency; using Abp.EntityFramework; using Abp.EntityFrameworkCore.Configuration; using Microsoft.EntityFrameworkCore; using System; using System.Data.Common; using System.Reflection; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Metadata.Internal; using System.Linq; namespace Abp.EntityFrameworkCore { public class DefaultDbContextResolver : IDbContextResolver, ITransientDependency { // ... 其他代码 public TDbContext Resolve<TDbContext>(string connectionString, DbConnection existingConnection) where TDbContext : DbContext { // ... 其他代码 try { if (isAbstractDbContext) { // return (TDbContext) _iocResolver.Resolve(concreteType, new // { // options = CreateOptionsForType(concreteType, connectionString, existingConnection) // }); return (TDbContext) _iocResolver.Resolve(concreteType, new object[] { CreateOptionsForType(concreteType, connectionString, existingConnection) }); } // return _iocResolver.Resolve<TDbContext>(new // { // options = CreateOptions<TDbContext>(connectionString, existingConnection) // }); return _iocResolver.Resolve<TDbContext>(new object[] { CreateOptions<TDbContext>(connectionString, existingConnection) }); } catch (Castle.MicroKernel.Resolvers.DependencyResolverException ex) { // ... 其他代码 } // ... 其他代码 } // ... 其他代码 } }

至此,针对于 EFCore 相关的库改造就已经成功完成了。

4.3 ASP .NET Core 相关改造

到目前,我们已经针对 Abp 的核心库和 EF Core 库都进行了一些不算大的改动,现在就只剩 Abp.AspNetCore 库了。因为 .NET Core 自己使用了一套 DI 框架。而我们在之前的源码分析也有讲到过,通过更改 Startup 类的 ConfigureService() 方法的返回值为 IServiceProvider,就可以将原来内部的 DI 框架替换为其他的 DI 框架。

在原来 Abp.AspNetCore 库的 AbpServiceCollectionExtensions 扩展类当中可以看到以下代码:

public static IServiceProvider AddAbp<TStartupModule>(this IServiceCollection services, [CanBeNull] Action<AbpBootstrapperOptions> optionsAction = null) where TStartupModule : AbpModule { var abpBootstrapper = AddAbpBootstrapper<TStartupModule>(services, optionsAction); ConfigureAspNetCore(services, abpBootstrapper.IocManager); return WindsorRegistrationHelper.CreateServiceProvider(abpBootstrapper.IocManager.IocContainer, services); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyypz.html