确定要从另一个程序集创建的对象类 [英] Decide class of object to be created from another assembly

查看:25
本文介绍了确定要从另一个程序集创建的对象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 .net 程序集,它公开一个公共类(名为 A),以便使用反射 (Assembly.CreateInstance) 创建其他程序.目前,它工作正常.

I have a .net assembly that exposes a public class (named A) to be created other programs using reflection (Assembly.CreateInstance). For now, it works fine.

但现在我有 A 的两个子类,比如 A1 和 A2,我需要创建一个或另一个,这取决于运行时检查.客户端不能修改,应该相信返回的对象是A类.

But now I have two subclasses of A, say A1 and A2, and I need to create one or the other, depending on a runtime check. The client cannot be modified, it should believe that the object returned is of class A.

如果我使用 COM 而不是 .net,那就很简单了:只需将检查添加到 IClassFactory.CreateInstance 中即可.但是有没有办法在 .net 中做到这一点?

If I were using COM instead of .net, it would be easy enough: simply add the check into the IClassFactory.CreateInstance and be done. But is there a way to do this in .net?

注意:使用代理对象或类似对象的明显解决方案是不切实际的,因为类 A 有数百个方法 (!),我不想重新路由所有方法.

Note: the obvious solution of using a proxy object, or similar, is not practical, because class A has several hundred methods (!) and I don't want to reroute all of them.

推荐答案

首先,应该注意的是,如果您的客户端可以使用您提供的工厂方法而不是劫持 Activator.CreateInstance 会更容易.请在阅读之前充分考虑...

Firstly, it should be noted that it would be easier if your client could use a factory method that you provide rather than having to hijack Activator.CreateInstance. Please consider that fully before reading on...

这是一个使用 ContextBoundObject 的例子 - 它使用一个计数器作为运行时检查"来决定 BC 作为实际对象,即使调用者要求 A.请注意,如果他们使用 new A(),这也适用.

Here's an example using ContextBoundObject - it uses a counter as the "runtime check" to decide between B and C as the actual object, even though the caller asked for an A. Note that this also works if they used new A().

private static void Main()
{
    // subvert Activator.CreateInstance
    for(int i = 0 ; i < 100 ; i++)
    {
        object obj = Activator.CreateInstance(typeof (A));
        Console.WriteLine(obj.GetType().Name);
    }
    // subvert "new()"
    for(int i = 0 ; i < 100 ; i++)
    {
        object obj = new A();
        Console.WriteLine(obj.GetType().Name);
    }
}

class AProxyAttribute : ProxyAttribute
{
    int flipper;
    public override MarshalByRefObject CreateInstance(Type serverType)
    {
        if (serverType == typeof(A))
        {
            return ((flipper++)%2) == 0 ? (A) new B() : (A) new C();
        }
        return base.CreateInstance(serverType);
    }
}
[AProxy]
class A : ContextBoundObject { }
// the two subclasses
class B : A {}
class C : A{}

所以,是的,您可以卑鄙地向来电者撒谎,向来电者退还他们要求的东西;p 不过,这是相当邪恶的代码.YMMV等

So yes, you can be dastardly and lie to the caller by giving them back something other than they asked for ;p This is fairly evil code, though. YMMV etc.

这篇关于确定要从另一个程序集创建的对象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆