WebApi 的三种寄宿方式 (二) - 宿主和控制器不在一个程序集
新建一个类库:
SelfHost:
方法一:
1.添加对MyControllers类库的引用.
2.在控制台代码中加入一行代码:
当然,可以添加多个程序集.(记得引用)
var config = new HttpSelfHostConfiguration("http://localhost:9527"); config.Routes.MapHttpRoute( "API Default", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }); //加载外部程序集 Assembly.Load("MyControllers"); using (var server = new HttpSelfHostServer(config)) { server.OpenAsync().Wait(); Console.WriteLine("请开始您的表演"); Console.ReadLine(); }
3.测试结果:
方法二:
1.新建自定义的 AssembliesResolver 类
View Code
2.修改控制台代码:
var config = new HttpSelfHostConfiguration("http://localhost:9527"); config.Routes.MapHttpRoute( "API Default", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional }); //加载外部程序集 //Assembly.Load("MyControllers"); //Assembly.Load("TestControllers"); config.Services.Replace(typeof(IAssembliesResolver), new MyAssembiesResolver()); using (var server = new HttpSelfHostServer(config)) { server.OpenAsync().Wait(); Console.WriteLine("请开始您的表演"); Console.ReadLine(); }
实际上就添了一行代码...
3.测试:
上面的方法将程序集写死在代码里,这肯定不符合要求.
方法三:
新建3个类,如下:
public class AppConfigSetting { public static string AssembliesLoadFrom => GetValue(); public static string GetValue([CallerMemberName]string key = null) { return System.Configuration.ConfigurationManager.AppSettings[key]; } }
public class AssembliesLoad : ConfigurationSection { [ConfigurationProperty("", IsDefaultCollection = true)] public AssemblyElementCollection AssemblyNames { get { return (AssemblyElementCollection)this[""]; } } public static AssembliesLoad GetSection() { return ConfigurationManager.GetSection(AppConfigSetting.AssembliesLoadFrom) as AssembliesLoad; } } public class AssemblyElementCollection : ConfigurationElementCollection { protected override ConfigurationElement CreateNewElement() { return new AssemblyElement(); } protected override object GetElementKey(ConfigurationElement element) { AssemblyElement serviceTypeElement = (AssemblyElement)element; return serviceTypeElement.AssemblyName; } } public class AssemblyElement : ConfigurationElement { [ConfigurationProperty("assemblyName", IsRequired = true)] public string AssemblyName { get { return (string)this["assemblyName"]; } set { this["assemblyName"] = value; } } }
public class WebApiResolver : DefaultAssembliesResolver { public override ICollection<Assembly> GetAssemblies() { AssembliesLoad settings = AssembliesLoad.GetSection(); if (null != settings) { try { foreach (AssemblyElement element in settings.AssemblyNames) { AssemblyName assemblyName = AssemblyName.GetAssemblyName(element.AssemblyName); if (!AppDomain.CurrentDomain.GetAssemblies().Any(assembly => AssemblyName.ReferenceMatchesDefinition(assembly.GetName(), assemblyName))) { AppDomain.CurrentDomain.Load(assemblyName); } } } catch (Exception e) { } } return base.GetAssemblies(); } }
修改配置文件:
<configuration> <configSections> <section name="test1" type="SelfHost.AssembliesLoad,SelfHost"/> <section name="test2" type="SelfHost.AssembliesLoad,SelfHost"/> </configSections> <appSettings> <add key="AssembliesLoadFrom" value="test1"/> </appSettings> <test1> <add assemblyName="MyControllers.dll" /> <add assemblyName="TestControllers.dll" /> </test1> <test2> <add assemblyName="Wjire.Controllers.dll" /> </test2> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> </configuration>
修改控制台代码:
测试结果就不贴了.
OwinSelfHost:
目前不知道怎么使用配置文件的方式,因为只要添加了程序集的引用,Owin就能找到里面的控制器,
就算采用上面的方法三也没有什么用,还是全部都能访问到
额外:
1.如果不同的程序集中有相同名字的控制器,那么会报错