Создание универсального типа с помощью универсального интерфейса во время выполнения

Я работаю над проблемой уже пару часов, и, кажется, я близок к этому. Я работаю над приложением, в котором у нас может быть 50-100 типов, работающих одинаково. Поэтому вместо того, чтобы создавать 50-100 классов, я попытался сделать его универсальным, и вот что у меня есть:

Это базовый класс:

public class RavenWriterBase<T> : IRavenWriter<T> where T : class, IDataEntity

А это интерфейс:

public interface IRavenWriter<T>
{
    int ExecutionIntervalInSeconds { get; }
    void Execute(object stateInfo);
    void Initialize(int executionIntervalInSeconds, Expression<Func<T, DateTime>> timeOrderByFunc);
}

И вот как я используя его:

private static void StartWriters()
{
    Assembly assembly = typeof(IDataEntity).Assembly;
    List<IDataEntity> dataEntities = ReflectionUtility.GetObjectsForAnInterface<IDataEntity>(assembly);

    foreach (IDataEntity dataEntity in dataEntities)
    {
        Type dataEntityType = dataEntity.GetType();
        Type ravenWriterType = typeof(RavenWriterBase<>).MakeGenericType(dataEntityType);

        Expression<Func<IDataEntity, DateTime>> func = x => x.CicReadTime;

        // This is where I'm stuck. How do I activate this as RavenWriterBase<T>?
        var ravenWriter = Activator.CreateInstance(ravenWriterType);

        //ravenWriter.Initialize(60, func);  // I can't do this until I cast.

        // More functionality here (not part of this issue)
    }
}

Я застрял на этой строке сверху:

var ravenWriter = Activator.CreateInstance(ravenWriterType);

Это мой вопрос:
Как я могу использовать это как RavenWriterBase или IRavenWriter? Что-то вроде:

ravenWriter.Initialize(60, func);

Я думаю, что это должно быть что-то вроде этого, но мне нужно указать тип для IRavenWriter<>, и я еще не знаю этого:

var ravenWriter = Activator.CreateInstance(ravenWriterType) as IRavenWriter<>;

Если я наведу курсор на ravenWriter, я успешно получу свой объект :

enter image description here

Но теперь мне нужно иметь возможность использовать его в общем виде. Как я могу это сделать?

Обновление:

Я только что подумал об использовании динамического ключевого слова, и это работает:

dynamic ravenWriter = Activator.CreateInstance(ravenWriterType);
ravenWriter.Initialize(60);

Я немного схитрил, потому что понял, что Func был одинаковым для каждого IDataEntity, так что не было необходимости передавать как параметр для Initialize(). Однако, по крайней мере, теперь я могувызвать Initialize(). Но теперь, когда Func тот же, мне не нужен и общий интерфейс.

5
задан Bob Horn 13 April 2012 в 17:17
поделиться