Как можно безопасно загрузить код из нескольких источников, имеющих дело с неизвестным типом? - PullRequest
3 голосов
/ 08 августа 2010

Мне нужно иметь возможность во время выполнения загружать два класса, которые имеют неизвестный тип, например:

interface IProducer<out A>
{
    public A CookOne();
}

interface IConsumer<in A>
{
    public void EatOne(A food);
}

Вот два примера классов

class IntChef : IProducer<int>
{
    private int _counter = 0;

    public int CookOne()
    {
        return counter++;
    }
}

class IntCustomer : IConsumer<int>
{
    public void EatOne(int food)
    {
        Console.WriteLine("I ate a {0}", food);
    }
}

Цель состоит в том, чтобы загрузить реализацию каждого интерфейса, совместно используя тип, с которым они взаимодействуют, и создать новый объект, которому все равно, как взаимодействуют два загруженных типа.

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

interface IStrategyFactory<A>
{
    public IStrategy MakeAStrategy(IProducer<A> producer, IConsumer<A> consumer);
}

interface IStrategy
{
    public void DoSomething();;
}

Как загрузить внешний двоичный код (из двух разных источников) и передать его на завод (или где-либо еще) безопасным для типов способом, так что я не могу, например, передать IProducer и IConsumer?

Лучший ресурс, который я могу найти на данный момент, это http://codebetter.com/blogs/glenn.block/archive/2009/08/20/open-generic-support-in-mef.aspx

Оптимально сама программа будетесть такие типы:

interface IStrategyFactory<A>
{
    public IStrategy MakeAStrategy(IProducer<A> producer, IConsumer<A> consumer);
}

interface IStrategy
{
    public void DoSomething();;
}

1 Ответ

0 голосов
/ 25 февраля 2011

Вы можете использовать отражение для создания новых объектов во время выполнения, даже общих классов. Вы можете создать фабрику классов, которая загружает их на основе файла конфигурации, в котором перечислены типы. Похоже, вы в основном ищете контейнер IOC . Это в основном то, что делает проект Windsor-Castle , с добавлением приятного интерфейса. Это может не соответствовать вашим конкретным потребностям, но есть много других проектов с открытым исходным кодом, которые могут работать для вас.

Я бы также предложил вам использовать интерфейс для определения методов, которые вы хотите использовать в ваших методах CookOne и EatOne, и добавить общее ограничение к интерфейсам IProducer и IConsumer.

interface ISomethingOrOther{}

interface IProducer<out A> where A : ISomethingOrOther
{
    public A CookOne();
}

interface IConsumer<in A> where A : ISomethingOrOther
{
    public void EatOne(A food);
}
...