当自主托管时,似乎没有一种开箱即用的方法可以自动托管在app.config文件中的服务。我发现这个问题提到了可能的解决方案:此问题,即在运行时动态枚举列在app.config中的服务,并为每个服务创建ServiceHost。
然而,我的服务、合同和托管应用程序都位于不同的程序集中。这导致Type.GetType(string name)无法找到我的服务类型(返回null),因为它在不同的程序集中定义。
如何可靠地动态托管app.config文件中列出的所有服务(即,在我的自主托管应用程序中不硬编码new ServiceHost(typeof(MyService)))?
注:我的app.config是使用Visual Studio 2010中的“WCF Configuration Editor”生成的。
还要注意:我的主要目标是通过app.config文件来驱动这一切,以便有一个单一的配置点。我不想在其他位置进行配置。
编辑:我能够读取app.config文件(请参见此处),但需要能够解析不同程序集中的类型。
编辑:下面的一个答案促使我尝试在app.config中指定AssemblyQualifiedName,而不仅是基本类型名称。这能够解决Type.GetType()问题,但ServiceHost.Open()现在无论如何获得类型都会失败并引发InvalidOperationException。
// Fails
string typeName = typeof(MyService).AssemblyQualifiedName;
Type myType = Type.GetType(typeName);
ServiceHost host = new ServiceHost(myType);
host.Open(); // throws InvalidOperationException
// Also fails
Type myType2 = typeof(MyService);
ServiceHost host2 = new ServiceHost(myType2);
host2.Open(); // throws InvalidOperationException
异常详情:
服务 'SO.Example.MyService' 没有任何应用程序(非基础设施)端点。这可能是因为找不到您的应用程序的配置文件,或者因为在配置文件中找不到与服务名称匹配的服务元素,或者因为在服务元素中未定义端点。
我猜 WCF 在解析内部的 app.config 文件时尝试匹配服务名称的字面字符串。
编辑/答案:最终我做的基本上就是下面答案中的方法。我没有使用 Type.GetType()
,而是知道我的所有服务都在同一个程序集中,所以我切换到了:
// Get a reference to the assembly which contain all of the service implementations.
Assembly implementationAssembly = Assembly.GetAssembly(typeof(MyService));
...
// When loading the type for the service, load it from the implementing assembly.
Type implementation = implementationAssembly.GetType(serviceElement.Name);
name=
属性值必须与实现该 WCF 服务的类的完全限定名称完全匹配。不允许对该属性进行任何调整或“扩展”。 - marc_s