Внедрение зависимостей в Entity Framework - PullRequest
0 голосов
/ 05 января 2019

Я хочу знать, как работает внедрение зависимостей в 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();
    }

Этот код найден DbSet<> в DbContext, но не находит членов, которые унаследованы от DbSet<>. Это означает, что я должен расширить код методом Type.IsAssignableFrom(Type), чтобы найти и унаследованные экземпляры.

И я хочу переопределить по умолчанию IDbSetFinder с моим классом DbSetFinder, EFCore обеспечивает его функциональность. Просто я не знаю, где я могу это сделать, и когда я могу это сделать.

Существует ServiceProvider и возможность изменить реализацию, но я не знаю, как это сделать.

Существует класс, в котором установлены зависимости основной службы:

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

Как я могу связаться с этим поставщиком услуг до того, как он заполняется значениями по умолчанию, и как я могу изменить его реализацию.

1 Ответ

0 голосов
/ 05 января 2019

Самый простой (и, вероятно, предполагаемый публичный) способ - переопределить OnConfiguring и использовать DbContextOptionsBuilder.ReplaceService метод:

Заменяет внутреннюю реализацию Entity Framework контракта на обслуживание другой реализацией.

1010 *, например *

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.ReplaceService<IDbSetFinder, CustomDbSetFinder>();
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...