我试图在运行时不知道其类型/接口的情况下创建WCF服务。为此,我使用ChannelFactory。 ChannelFactory是一个泛型类,所以我需要使用Type.MakeGenericType。传递给MakeGenericType的类型来自我之前通过搜索某些程序集而使用反射收集的接口列表。
最后,我调用MethodInfo.Invoke来创建对象。该对象创建得很好,但我无法将其转换为正确的接口。在投射时,我收到以下错误:
“无法将透明代理转换为输入'Tssc.Services.MyType.IMyType'”
经过一些实验,我发现传递给MakeGenericType的接口/类型似乎是个问题。如果我用我的实际界面替换列表中的界面,那么一切正常。我梳理了两个物体,看不出有什么区别。当我修改代码以生成两种类型时,将它们与Equals进行比较将返回false。我不清楚Equals是否只是检查它们是指同一个对象(不是),还是检查所有属性等等。
这是否与我收集界面的方式有关(反思,保存在列表中......)?对象的比较似乎表明它们是等价的。我打印了两个对象的所有属性,它们是相同的。我需要深入挖掘吗?如果是这样,进入哪里?
// createService() method
//*** tried both of these interfaces, only 2nd works - but they seem to be identical
//Type t = interfaces[i]; // get type from list created above - doesn't work
Type t = typeof(Tssc.Services.MyType.IMyType); // actual type - works OK
// create ChannelFactory type with my type parameter (t)
Type factoryType = typeof(ChannelFactory<>);
factoryType = factoryType.MakeGenericType(new Type[] { t });
// create ChannelFactory<> object with two-param ctor
BasicHttpBinding binding = new BasicHttpBinding();
string address = "blah blah blah";
var factory = Activator.CreateInstance(factoryType, new object[] { binding, address });
// get overload of ChannelFactory<>.CreateChannel with no parameters
MethodInfo method = factoryType.GetMethod("CreateChannel", new Type[] { });
return method.Invoke(factory, null);
//--------------- code that calls code above and uses its return
object ob = createService();
//*** this cast fails
Tssc.Services.MyType.IMyType service = (Tssc.Services.MyType.IMyType)ob;
答案 0 :(得分:0)
好的,我理解这里发生了什么 - 问题与加载相同的程序集有效加载两次有关 - 一次是通过引用,一次是通过程序集加载命令。您需要做的是更改加载程序集的位置,并检查当前AppDomain中是否已存在,如下所示:
Assembly assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name.Equals("ClassLibrary1Name"));
if (assembly == null)
{
assembly = System.Reflection.Assembly.LoadFile("path to your assembly");
}
//do your work here
这样,如果程序集已经加载到内存中,它将使用那个。