从另一个组件创建确定类对象的 [英] Decide class of object to be created from another assembly
问题描述
我有一个公开一个公共类(命名为A)要创建使用反射(Assembly.CreateInstance)其他程序.NET程序集。现在,它工作正常。
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.
但现在我有两个子类,比如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
的例子 - 它使用一个柜台的运行时检查 B
之间决定 C
为实际的对象,即使来电询问一个 A
。请注意,这也适用,如果他们使用新的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这是相当邪恶code,虽然。因人而异等。
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屋!