-
-
Save HenrikFrystykNielsen/2907767 to your computer and use it in GitHub Desktop.
using System; | |
using System.Collections.Generic; | |
using System.Reflection; | |
using System.Threading.Tasks; | |
using System.Web.Http; | |
using System.Web.Http.Dispatcher; | |
using System.Web.Http.SelfHost; | |
namespace SelfHost | |
{ | |
class Program | |
{ | |
static HttpSelfHostServer CreateHost(string address) | |
{ | |
// Create normal config | |
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(address); | |
// Set our own assembly resolver where we add the assemblies we need | |
AssembliesResolver assemblyResolver = new AssembliesResolver(); | |
config.Services.Replace(typeof(IAssembliesResolver), assemblyResolver); | |
// Add a route | |
config.Routes.MapHttpRoute( | |
name: "default", | |
routeTemplate: "api/{controller}/{id}", | |
defaults: new { controller = "Home", id = RouteParameter.Optional }); | |
HttpSelfHostServer server = new HttpSelfHostServer(config); | |
server.OpenAsync().Wait(); | |
Console.WriteLine("Listening on " + address); | |
return server; | |
} | |
static void Main(string[] args) | |
{ | |
// Create and open our host | |
HttpSelfHostServer server = CreateHost("http://localhost:8080"); | |
Console.WriteLine("Hit ENTER to exit..."); | |
Console.ReadLine(); | |
} | |
} | |
class AssembliesResolver : DefaultAssembliesResolver | |
{ | |
public override ICollection<Assembly> GetAssemblies() | |
{ | |
ICollection<Assembly> baseAssemblies = base.GetAssemblies(); | |
List<Assembly> assemblies = new List<Assembly>(baseAssemblies); | |
// Add whatever additional assemblies you wish | |
return assemblies; | |
} | |
} | |
} |
I created a controller assembly containing all my controllers in WebApi 2.0 and created a CustomAssemblyResolver and added code to replace the assembly resolver in Application_Start. Here's what my code looks like:
My CustomAssemblyResolver:
public class CustomAssemblyResolver : DefaultAssembliesResolver
{
public override ICollection<Assembly> GetAssemblies()
{
ICollection<Assembly> baseAssemblies = base.GetAssemblies();
List<Assembly> assemblies = new List<Assembly>(baseAssemblies);
string thirdPartySource = "C:\\Research\\ExCoWebApi\\ExternalControllers";
if (!string.IsNullOrWhiteSpace(thirdPartySource))
{
if (Directory.Exists(thirdPartySource))
{
foreach (var file in Directory.GetFiles(thirdPartySource, "*.*", SearchOption.AllDirectories))
{
if (Path.GetExtension(file) == ".dll")
{
var externalAssembly = Assembly.LoadFrom(file);
baseAssemblies.Add(externalAssembly);
}
}
}
}
return baseAssemblies;
}
}
My Application_Start:
protected void Application_Start()
{
Debugger.Launch();
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.Services.Replace(typeof(IAssembliesResolver), new CustomAssemblyResolver());
}
As you can see I'm replacing the default assembly resolver with a CustomAssemblyResolver.
Here's how I'm registering route to the third party controller:
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapHttpRoute(
name: "Test",
routeTemplate: "api/thirdparty/math",
defaults: new { controller = "Math" }
);
}
This is how my MathController looks like that lives in a separate assembly:
public class MathController : ApiController
{
[HttpPost]
public int AddValues(MathRequest request)
{
int response = MathOperations.Add(request.Value1, request.Value2);
return response;
}
}
This is the endpoint I hit via postman: http://localhost/ExCoWebApi/api/thirdparty/math with a POST operation and MathRequest JSON string in the Body and this is what I get as a response:
{ "Message": "No HTTP resource was found that matches the request URI 'http://localhost/ExCoWebApi/api/thirdparty/math'.", "MessageDetail": "No type was found that matches the controller named 'Math'." }
After debugging I found that the AssemblyResolver does get replaced with CustomAssemblyResolver at the Application Start but the problem is the GetAssemblies() method of CustomAssemblyResolver doesn't get called. Hence the assembly containing MathController doesn't get loaded.
What am I missing here??
How do acheive this in ASP.NET Core 5.0 ?
Also check out AutoFac: https://code.google.com/p/autofac/wiki/WebApiIntegration for dependency resolving.