Вызовите перегруженный метод сторонней сборки из универсального метода, используя динамический (или другими способами)?

Обновление: оказалось, что были детали, которые я полностью пропустил, пока я не посмотрел на исходный код библиотеки, которую я использовал. Извиняюсь за плохой пример кода, пытаясь сосредоточиться на том, что я считаю уместным.

Работа с библиотекой FlatFiles NuGet, которая имеет 25 перегрузок для Property(...) метод. Я пытаюсь отправить правильный Property(...) перегрузка из моего универсального метода с использованием динамического параметра, который я передаю, но это не работает. Вот что я попробовал:

using FlatFiles;
using FlatFiles.TypeMapping;

public class FixedWidthDataSource<FixedWidthRecordT> {
    public IFixedLengthTypeMapper<FixedWidthRecordT> Mapper
        = FixedLengthTypeMapper.Define<FixedWidthRecordT>()
    ;
    ...
    public void MapProperty<T>(
        Expression<Func<FixedWidthRecordT, T>> col
        , int width
        , string inputFormat = null
    ) {
        var window = new Window(width);
        Mapper.Property((dynamic)col, window);
    }
}

public class FixedWidthRecord
{
    public string First { get; set; }
    public string Last { get; set; }
}

//later
var fwds = new FixedWidthDataSource<FixedWidthRecord>();
fwds.MapProperty(c=>c.First, 5);

Несколько перегрузок Собственности:

Property(Expression<Func<FixedWidthRecordT, bool>> property, Window window);
Property(Expression<Func<FixedWidthRecordT, int>> property, Window window);
Property(Expression<Func<FixedWidthRecordT, string>> property, Window window);

Я получаю ошибку 'FlatFiles.TypeMapping.IFixedLengthTypeMapper<FixedWidthRecord>' does not contain a definition for 'Property',

Глядя на источник, я вижу, что есть internal sealed class FixedLengthTypeMapper<TEntity> и это тип объекта, который возвращается из вызова FixedLengthTypeMapper.Define<FixedWidthRecordT>() и назначен Mapper, Тем не мение, IFixedLengthTypeMapper не имеет каких-либо определений для Property(...), только FixedLengthTypeMapper есть их.

Надеюсь, что все это актуально.

2 ответа

Решение

Вот что я наконец-то сделал, чтобы заставить его работать, хотя он использовал интерфейс, не описанный в документации по использованию библиотеки. Мне все еще любопытно, как это могло бы быть иначе решено (скажем, например, если интерфейс IFixedLengthTypeConfiguration, который я использую в решении, также был определен как внутренний).

using FlatFiles;
using FlatFiles.TypeMapping;

public class FixedWidthDataSource<FixedWidthRecordT> {
    public IFixedLengthTypeConfiguration<FixedWidthRecordT> Configuration
        = FixedLengthTypeMapper.Define<FixedWidthRecordT>()
    ;
    public IFixedLengthTypeMapper<FixedWidthRecordT> Mapper;
    public FixedWidthDataSource() {
        Mapper = (IFixedLengthTypeMapper<FixedWidthRecordT>)Configuration;
    }
    ...
    public void MapProperty<T>(
        Expression<Func<FixedWidthRecordT, T>> col
        , int width
        , string inputFormat = null
    ) {
        var window = new Window(width);
        Configuration.Property((dynamic)col, window);
    }
}

public class FixedWidthRecord
{
    public string First { get; set; }
    public string Last { get; set; }
}

//later
var fwds = new FixedWidthDataSource<FixedWidthRecord>();
fwds.MapProperty(c=>c.First, 5);

Может быть, ваше дело как-то связано с этим? RuntimeBinderException - "не содержит определения для".

Эта статья получает это исключение в случае анонимного объекта, но ваш случай кажется похожим. Ваша сборка пытается получить доступ к чему-либо через dynamic он не может нормально видеть: internal класс в вашем случае, анонимный тип в их.

Добавление [assembly: InternalsVisibleTo("Your.Assembly")] Атрибут в библиотеке не выглядит хорошим вариантом, но если вы можете построить из исходного кода, он может помочь временно. Или, может быть, с этой информацией вы могли бы создать надежную копию.

Другие вопросы по тегам