开发者

How can I type safely load code from multiple sources that deal with an unknown type?

开发者 https://www.devze.com 2023-01-10 12:05 出处:网络
I need to be able to, at runtime, load two classes that share an unknown type, like this: interface IProducer<out A>

I need to be able to, at runtime, load two classes that share an unknown type, like this:

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

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

<edit>

Here are two example classes

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

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

开发者_如何学JAVAclass IntCustomer : IConsumer<int>
{
    public void EatOne(int food)
    {
        Console.WriteLine("I ate a {0}", food);
    }
}

The goal is to load an implementation of each interface, sharing the type they communicate via, and create a new object that doesn't care how the two loaded types communicate.

</edit>

The entire list of possible involved types can't be known at compile time because they don't exist yet. The software that uses these types is something like this:

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

interface IStrategy
{
    public void DoSomething();;
}

How can I load external binary code (from two different sources) and pass them to the factory (or wherever else) in a type-safe manner, so that I can't, for example, pass in a IProducer and an IConsumer?

The best resource I can find on this so far is http://codebetter.com/blogs/glenn.block/archive/2009/08/20/open-generic-support-in-mef.aspx

Optimally the program itself would have types like this:

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

interface IStrategy
{
    public void DoSomething();;
}


You can use reflection to create new objects at runtime, even generic classes. You can create a class factory that loads them based on a configuration file that lists out the types. It sounds like you're basically looking for an IOC container. That's basically what the Windsor-Castle project does, with the addition of a nice interface. That may not fit your exact needs, but there's many other open-source projects out there that may work for you.

I would also suggest you use an interface to define the methods you want to use in your CookOne and EatOne methods, and to add a generic constraint to the IProducer and IConsumer interfaces.

interface ISomethingOrOther{}

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

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号