实体框架依赖注入

4

我想了解EFCore中依赖注入的工作原理。

我想改变DbSetFinder的行为,不仅可以查找DbSet<>DbQuery<>成员,而且还可以查找从它继承的成员。

当前的代码如下:

    private static DbSetProperty[] FindSets(Type contextType)
    {
        var factory = new ClrPropertySetterFactory();

        return contextType.GetRuntimeProperties()
            .Where(
                p => !p.IsStatic()
                     && !p.GetIndexParameters().Any()
                     && p.DeclaringType != typeof(DbContext)
                     && p.PropertyType.GetTypeInfo().IsGenericType
                     && (p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>)
                         || p.PropertyType.GetGenericTypeDefinition() == typeof(DbQuery<>)))
            .OrderBy(p => p.Name)
            .Select(
                p => new DbSetProperty(
                    p.Name,
                    p.PropertyType.GetTypeInfo().GenericTypeArguments.Single(),
                    p.SetMethod == null ? null : factory.Create(p),
                    p.PropertyType.GetGenericTypeDefinition() == typeof(DbQuery<>)))
            .ToArray();
    }

这段代码在DbContext中找到了DbSet<>,但没有找到从DbSet<>继承的成员。

这意味着我需要使用Type.IsAssignableFrom(Type)方法来扩展代码,以便找到继承的实例。

我想用我的DbSetFinder类覆盖默认的IDbSetFinder,EFCore为此提供了功能。只是我不知道在哪里可以做到这一点,以及何时可以这样做。

有一个ServiceProvider和更改实现的可能性,但我不知道如何做到这一点。

有一个类设置了核心服务依赖项:

    public virtual EntityFrameworkServicesBuilder TryAddCoreServices()
    {
        TryAdd<IDbSetFinder, DbSetFinder>();
        TryAdd<IDbSetInitializer, DbSetInitializer>();
        TryAdd<IDbSetSource, DbSetSource>();
        TryAdd<IDbQuerySource, DbSetSource>();
        ...

如何在服务提供商填充默认值之前联系到它,并且如何更改它的实现。
1个回答

6
最简单的(也可能是预期的公开)方式是重写 OnConfiguring 方法并使用 DbContextOptionsBuilder.ReplaceService 方法:

使用不同的实现替换服务契约的内部 Entity Framework 实现。

例如:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.ReplaceService<IDbSetFinder, CustomDbSetFinder>();
    // ...
}

我该如何从给定的上下文中提取 IDbSetFinder - Shimmy Weitzhandler
1
@Shimmy 就像任何 EF Core 内部服务一样,您需要使用 using Microsoft.EntityFrameworkCore.Infrastructure; 来访问 AccessorExtensions,特别是 GetService<T> 扩展方法,它是 EF Core 服务定位器,例如 var dbSetFinder = dbContext.GetService<IDbSetFinder>(); - Ivan Stoev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接