如何从处理未知类型的多个源安全地键入加载代码?

发布于 2024-09-13 00:53:44 字数 1457 浏览 8 评论 0原文

我需要能够在运行时加载两个共享未知类型的类,如下所示

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();;
}

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++;
    }
}

class 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();;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

§普罗旺斯的薰衣草 2024-09-20 00:53:44

您可以使用反射在运行时创建新对象,甚至是泛型类。您可以创建一个类工厂,根据列出类型的配置文件加载它们。听起来您基本上是在寻找 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);
}

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文