当前位置: 首页 > 编程语言 > C#

使用SelfHosting时,是否可以自动托管app.config中的所有服务?分享

时间:2023-04-10 16:57:48 C#

使用SelfHosting时,我可以在app.config中自动托管所有服务吗?我正在编写一个需要托管多个WCF服务的应用程序。WCF的优势之一是能够通过在app.config文件中指定设置来配置服务而无需重新编译。自托管时,似乎没有开箱即用的方法可以在app.config文件中自动托管服务。我发现这个问题提到了一种可能的解决方案,即在运行时动态枚举app.config中列出的服务并为每个服务创建一个ServiceHost。但是,我的服务、合同和托管应用程序都在不同的程序集中。这会导致Type.GetType(stringname)无法找到我的服务类型(返回null),因为它是在不同的程序集中定义的。如何在我的自托管应用程序中动态托管app.config文件中列出的所有服务(即没有硬编码newServiceHost(typeof(MyService))?注意:我的app.config使用VisualStudio2010生成的“WCF配置编辑器”。另请注意:我的主要目标由app.config文件驱动,因此只有一个配置点。我不想在一个位置配置它。编辑:我能够读取app.config文件(请参阅此处),但需要能够解析不同程序集中的类型。编辑:下面的答案之一提示我尝试在app.config中指定AssemblyQualifiedName而不仅仅是基本类型名称。这修复了Type.GetType()问题,但ServiceHost.Open()现在失败并出现InvalidOperationException,无论我如何获取类型://FailsstringtypeName=typeof(MyService).AssemblyQualifiedName;输入myType=Type.GetType(typeName);ServiceHosthost=newServiceHost(myType);主机.Open();//抛出InvalidOperationException//也失败TypemyType2=typeof(MyService);ServiceHosthost2=newServiceHost(myType2);host2.Open();//抛出InvalidOperationException异常详细信息:服务“SO.Example.MyService”具有零个应用程序(非基础结构)端点。这可能是因为没有为您的应用程序找到配置文件,或者因为在配置文件中找不到与服务名称匹配的服务元素,或者因为没有在服务元素中定义端点。我猜想在内部解析app.config文件时,WCF会尝试匹配服务名称的文字字符串。编辑/答案:我最终做的基本上是下面的答案。我知道我所有的服务都在同一个程序集中,而不是使用Type.GetType(),所以我切换到://获取对包含所有服务实现的程序集的引用。程序集实现Assembly=Assembly.GetAssembly(typeof(MyService));...//加载服务类型时,从实现程序集中加载它。类型implementation=implementationAssembly.GetType(serviceElement.Name);您在问题链接中正确地确定了问题的答案,@marc_s的答案也给出了正确的方法。您遇到的实际问题是,您需要动态获取可能只能通过配置文件引用的程序集的Type实例,因此它可能无法加载到当前的AppDomain中。查看此博客文章,了解在代码中动态引用程序集的方法。虽然该帖子专门针对ASP.NET应用程序,但一般方法应该适用于自托管方案。这个想法是用一个私有方法调用替换Type.GetType(string)调用,该方法调用动态加载请求的程序集(如果需要)并返回一个Type对象。您发送给此方法的参数仍然是element.Name,您需要确定要加载的是正确的程序集。一个简单的基于约定的程序集命名方案应该可以工作。例如,如果服务类型是:MyNamespace.MyService.MyServiceImpl假设程序集是:MyNamespace.MyService//getthe/configsectionServicesSectionservices=ConfigurationManager.GetSection("system.serviceModel/services")asServicesSection;//获取所有类varallTypes=AppDomain.CurrentDomain.GetAssemblies().ToList().SelectMany(s=>s.GetTypes()).Where(t=>t.IsClass==true);//枚举每个节点foreach(ServiceElementserviceinservices.Services){TypeserviceType=allTypes.SingleOrDefault(t=>t.FullName==service.Name);如果(服务类型==null){继续;}ServiceHostserviceHost=newServiceHost(serviceType);serviceHost.Open();根据其他答案,我将代码扩展为以下内容,它在app.config中搜索所有程序集中的服务这应该是可能的!查看此代码片段-以它为基础并从这里开始:usingSystem.Configuration;//不要忘记添加对此程序集的引用!//获取/config部分ServicesSectionservices=ConfigurationManager.GetSection("system.serviceModel/services")asServicesSection;//枚举每个节点foreach(ServiceElementaServiceinservices.Services){Console.WriteLine();Console.WriteLine("名称:{0}/行为:{1}",aService.Name,aService.BehaviorConfiguration);//枚举该服务的所有端点foreach(ServiceEndpointElementseeinaService.Endpoints){Console.WriteLine("tEndpoint:Address={0}/Binding={1}/Contract={2}",see.Address,see.绑定,见.Contract);}}只是暂时打印出信息——但您绝对可以使用它在NT服务中实际构建您自己的服务主机!更新:好的,抱歉,我错过了你最重要的一点-实际服务在不同的程序集中,在这种情况下你需要根据需要动态加载这些程序集-你可以“只是简单地知道”加载程序集,或者你可以把它们全部放入一个特定的子目录并加载该目录中的所有程序集,或者您可以只检查MyOwnServiceHost.exe所在的同一位置中的所有程序集,并检查是否找到您需要的任何类型的程序集。这部分-在哪个程序集中找到哪种服务类型-不是由WCF配置处理的-您需要自己执行此操作,无论哪种方式对您来说最有意义。以上是C#学习教程:使用SelfHosting时,是否可以自动托管app.config中的所有服务?如果分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注——//查找当前正在执行的程序集Assemblycurr=Assembly.GetExecutingAssembly();//在字符串中获取此应用程序运行的目录currentLocation=Path.GetDirectoryName(curr.Location);//查找该目录中的所有程序集string[]assemblies=Directory.GetFiles(currentLocation,"*.dll");//枚举那些程序集foreach(stringassemblyNameinassemblys){//加载程序集只是为了检查AssemblyassemblyToInspect=Assembly.ReflectionOnlyLoadFrom(assemblyName);if(assemblyToInspect!=null){//查找所有类型Type[]types=assemblyToInspect.GetTypes();//枚举类型并确定此程序集是否包含任何感兴趣的类型//例如,您可以在那些(服务实现)感兴趣的类型上放置一个“标记”接口,或者您可以使用特定的命名约定(所有类型//像“SomeThingOrAnootherService”-以“Service”结尾-是你的服务)//或某种查找表(例如,你需要从//解析app.config文件中找到的类型列表)foreach(Typetyintypes){//在这里做点什么}}}本文收集自网络,不代表立场,如涉及侵权,请点击右边联系管理员删除,如需转载请注明出处: