Skip to content

Instantly share code, notes, and snippets.

@jamesmh
Last active December 15, 2019 03:36
Show Gist options
  • Save jamesmh/d03e5380d051ed968729d06aa08eba80 to your computer and use it in GitHub Desktop.
Save jamesmh/d03e5380d051ed968729d06aa08eba80 to your computer and use it in GitHub Desktop.
Bind Coravel To .NET Framework (unsupported)
using Coravel;
using Coravel.Scheduling.Schedule.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Mvc;
[assembly: OwinStartupAttribute(typeof(CoravelFrameworkTest.App_Start.Startup))]
namespace CoravelFrameworkTest.App_Start
{
public partial class Startup
{
public void ConfigureServices(IServiceCollection services)
{
DependencyInjectionConfig.BindToFramework(services);
services.AddScheduler();
}
public void Configuration(IAppBuilder app)
{
var services = new ServiceCollection();
this.ConfigureServices(services);
var provider = services.BuildServiceProvider();
var resolver = new DefaultDependencyResolver(provider);
DependencyResolver.SetResolver(resolver);
// ------
// Add Coravel Scheduled tasks here.
// ------
provider.UseScheduler(scheduler =>
{
scheduler.ScheduleAsync(() =>
{
Debug.WriteLine("Scheduled task from coravel!");
return Task.CompletedTask;
}).EveryFiveSeconds();
});
// ------
// IHostedService is automatically executed by the .NET Core framework. This is a hack to "start" the
// Coravel scheduler's hosted service. Because of this, the hosted service isn't gracefully shutdown - among other
// unexpected situtations this might cause. But "it works!".
// ------
var hostType = typeof(IScheduler).Assembly.GetType("Coravel.Scheduling.HostedService.SchedulerHost");
var host = provider.GetService(hostType);
var instance = Activator.CreateInstance(hostType, new object[] { provider.GetService<IScheduler>(), Logger<object>.Make(hostType) });
var result = hostType.GetMethod("StartAsync").Invoke(instance, new object[] { new CancellationTokenSource().Token });
(result as Task).GetAwaiter().GetResult();
}
}
public class Logger<T> : ILogger<T>
{
public IDisposable BeginScope<TState>(TState state)
{
return new DummyDisposable();
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
}
public class DummyDisposable : IDisposable
{
public void Dispose() { }
}
public static object Make(Type type)
{
return Activator.CreateInstance(typeof(Logger<>).MakeGenericType(new Type[] { type }));
}
}
public class DefaultDependencyResolver : IDependencyResolver
{
protected IServiceProvider serviceProvider;
public DefaultDependencyResolver(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public object GetService(Type serviceType)
{
return this.serviceProvider.GetService(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return this.serviceProvider.GetServices(serviceType);
}
}
public static class DependencyInjectionConfig
{
public static void BindToFramework(IServiceCollection services)
{
// Configure all controllers for DI injection.
services.AddControllersAsServices(typeof(Startup).Assembly.GetExportedTypes()
.Where(t => !t.IsAbstract && !t.IsGenericTypeDefinition)
.Where(t => typeof(IController).IsAssignableFrom(t)
|| t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase)));
}
public static IServiceCollection AddControllersAsServices(this IServiceCollection services,
IEnumerable<Type> controllerTypes)
{
foreach (var type in controllerTypes)
{
services.AddTransient(type);
}
return services;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment