0

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.

to11mtm
  • 169
  • 6
  • @John Simple Injector's Documentation [appears to suggest this is not the correct way to do so](https://simpleinjector.readthedocs.io/en/latest/aspnetintegration.html) – to11mtm Dec 21 '18 at 02:54
  • That's interesting. It seems to add stuff to the default DI container, rather than acting as a container itself. – ProgrammingLlama Dec 21 '18 at 02:57
  • Please post the exception message for the torn lifestyle. And which versions are you using? – Steven Dec 21 '18 at 04:19
  • Added to my post; I will admit this appears to be a limitation moreso of Websharper than Simple Injector, per my comments in the edit. Thank you for building the first DI Framework that looked good enough for me to actually use, BTW! I've been using SI for a couple of years now and this is the closest to a pain point I've found (and, well, what I said above ;) Edit: Would a good option be to use [the static func method described here?](https://simpleinjector.org/blog/2016/07/working-around-the-asp-net-core-di-abstraction/) – to11mtm Dec 21 '18 at 04:26
  • Just an idea: Can't you add a singleton class which acts like a decorator as described [here](https://simpleinjector.readthedocs.io/en/latest/aop.html#decorators-with-func-t-decoratee-factories) – Ric .Net Dec 22 '18 at 15:11
  • @Ric.Net Yeah, That's what I was trying to get at with my other link, so it sounds like that is the best option. – to11mtm Dec 22 '18 at 20:54

0 Answers0