I'm trying to Convert an application I have working under a Basic Websharper Setup into an ASP.NET Core Application, Using Simple Injector for DI, but Cannot get the Configuration quite right. I think I'm missing a piece of abstraction Due to Websharper's Remoting Abstraction. How should I get the best of both worlds?
I'm using Websharper with the ASPNETCORE Nuget Package, SimpleInjector with the ASPNETCORE Nuget Package, and my own custom libraries.
I've gotten things to work as singletons with the code below, but I'd much rather be able to use proper scoping...
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSitelet<OddJobSitelet>()
//.AddWebSharperRemoting<OddJobRemoting>() //This will not work, results in a torn lifestyle related error
.AddAuthentication("WebSharper")
.AddCookie("WebSharper", options => { });
IntegrateSimpleInjector(services);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
InitializeContainer(app);
if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }
WebSharper.Core.Remoting.AddHandler(typeof(OddJobRemoting), container.GetService<OddJobRemoting>()); //This only takes an instance, which appears to preclude scoping.
app.UseAuthentication()
.UseStaticFiles()
.UseWebSharper()
.Run(context =>
{
context.Response.StatusCode = 404;
return context.Response.WriteAsync("Page not found");
});
}
public static void Main(string[] args)
{
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build()
.Run();
}
private Container container = new Container();
private void IntegrateSimpleInjector(IServiceCollection services)
{
/*services.Add(new ServiceDescriptor(typeof(OddJobRemoting), (aspnetCore) => container.GetService<OddJobRemoting>(), //Tried this, did not help since Websharper Remoting doesn't appear to use ServiceCollection this way*/
ServiceLifetime.Scoped));
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.EnableSimpleInjectorCrossWiring(container);
services.UseSimpleInjectorAspNetRequestScoping(container);
}
private void InitializeContainer(IApplicationBuilder app)
{
//If I use anything other than Lifestyle.Singleton for either the remoting Handler or my provider, It results in a torn lifestyle.
container.Register<IJobSearchProvider>(() =>
{
return new SQLiteJobQueueManager(new SQLiteJobQueueDataConnectionFactory(TempDevInfo.ConnString),
TempDevInfo.TableConfigurations["console"], new NullOnMissingTypeJobTypeResolver());
}, Lifestyle.Singleton);
container.Register<OddJobRemoting>(Lifestyle.Singleton);
// Allow Simple Injector to resolve services from ASP.NET Core.
container.AutoCrossWireAspNetComponents(app);
}
}
As Requested:
If I change the lifestyles from singleton, I will get the following Exception:
The OddJobRemoting is registered as 'Async Scoped' lifestyle, but the instance is requested outside the context of an active (Async Scoped) scope.
This happens on the line:
WebSharper.Core.Remoting.AddHandler(typeof(OddJobRemoting), container.GetService<OddJobRemoting>());
To note, I'm having to do this because Websharper's AddHandler
method requires an instance and appears to treat such as singletons internally.