0

我正在尝试在运行时不知道其类型/接口的情况下创建 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;
4

1 回答 1

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

这样,如果程序集已经加载到内存中,它将使用那个。

于 2013-02-20T16:33:56.963 回答