ritterim / stuntman

Library for impersonating users during development leveraging ASP.NET Identity.

Home Page:https://rimdev.io/stuntman/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ASP.NET Core Support

kendaleiv opened this issue Β· comments

  • Support CoreCLR

@khalidabuhakmeh I'm quite keen to port this .NET Core, so I had a bit of a crack at it last night. So far it's a pretty big shift however, as I've used the native .NET Core middleware rather than wrapping the previous Owin middleware.

Before I go any further, I wanted to check what your thoughts are about how it should proceed. I think a separate Stuntman.AspNetCore (or similar) package will be necessary, the question is how to keep everything properly factored.

We could split the Core project in to 3, the base Core project, the 4.5 package, and .NET Core package, with the latter 2 depending on the base Core project. However it seems a bit overkill for people to need 2 packages when the base Core project will literally only have a few classes in it.

Instead, I'm leaning toward just 2 projects with a bit of duplication + 2 separate test projects, separate samples etc.

But in that case, would it just be easier/clearer to split the core version out into a separate repo completely, which would probably simplify builds, packaging etc.

@andrewlock first of all, thanks for checking out stuntman. We love the idea of others taking an interest in our OSS projects.

Before I go any further, I wanted to check what your thoughts are about how it should proceed. I think a separate Stuntman.AspNetCore (or similar) package will be necessary, the question is how to keep everything properly factored.

Yes we have looked at porting during RC2 and we would like to support both the current .NET infrastructure (OWIN) and the new .NET Core infrastructure (IApplicationBuilder). This means two packages on Nuget.

We could split the Core project in to 3, the base Core project, the 4.5 package, and .NET Core package, with the latter 2 depending on the base Core project. However it seems a bit overkill for people to need 2 packages when the base Core project will literally only have a few classes in it.

That is one option, but we could also use compiler directives to achieve the same thing. Its not as pretty, but would reduce the number of projects.

Instead, I'm leaning toward just 2 projects with a bit of duplication + 2 separate test projects, separate samples etc.

I would prefer we convert the projects over to the new xproj setup and utilize the new project.json stuff and just have the minimal amount of projects required. Additionally, when it comes to samples we can have one sample project, since ASP.NET Core still supports OWIN (with a lot of hoop jumping), we can use the same web application with two diverging paths: /netcore/_stuntman and /owin/_stuntman. We would just have to register it twice in the sample.

But in that case, would it just be easier/clearer to split the core version out into a separate repo completely, which would probably simplify builds, packaging etc.

I don't want a separate repository because that would mean duplicating wiki, documentation, etc.. I think that is out of the question for me.

That all makes sense to me apart from the desire to have two packages on NuGet but potentially only one project (with compiler directives) for the actual project.

It seems like either having a single multi-targeted project and single nuget package, or two of each would be an easier way to go? I think the single project/package should be doable and probably makes the most sense.

And totally agree, duplicating the repo is overkill, don't know why I suggested it πŸ˜‰

@andrewlock I'm not sure one package is possible because the issue is you don't know what version of ASP.NET you are targeting, you only know the .NET version you are targeting. You can still build on top of the new infrastructure with the full .NET 4.6+ and use the IApplicationBuilder interface. Conversely, you could use the OWIN version with ASP.NET Core. The two (three) packages approach would delineate between the OWIN interface and the ASP.NET Core interface.

  • Stuntman
  • Stuntman.AspNetCore
  • Stuntman.OWIN

Where Stuntman could be versioned up to switch to a particular interface by default.

Nuget Version 1.0

  • Stuntman -> Stuntman.OWIN
  • Stuntman.OWIN -> Stuntman.OWIN
  • Stuntman.AspNetCore -> Stuntman.AspNetCore

Nuget Version 2.0

  • Stuntman -> Stuntman.AspNetCore
  • Stuntman.OWIN -> Stuntman.OWIN
  • Stuntman.AspNetCore -> Stuntman.AspNetCore

Ultimately, both packages would be versioned to the same number via SemVer.

This is just a "off the cuff" idea, and feedback is appreciated.

@kendaleiv @billboga @jrusbatch

@khalidabuhakmeh Ah, of course, I was thinking of it as 2 distinct targets - .NET 4.5 and OWIN or .NET Core and ASP.NET Core - instead of the combination of 4 we have in reality.

So, just to clarify, to support that combination we would need 3 'Main' projects

  • Stuntman - currently named Core in the solution, which could contain all the core classes from the current project, targeting both .NET 4.6 and .NET Core
  • Stuntman.OWIN - would contain the existing IAppBuilderExtensions class, targeting both .NET 4.6 and .NET Core
  • Stuntman.AspNetCore - which would contain a new implementation, IApplicationBuilderExtensions designed to work with ASP.NET Core, and targeting .NET 4.6 and .NET Core.

I think that should work pretty well, if I have understood you correctly there? If so then I think the upgrade route is pretty clear:

  • Convert to xproj with existing code base, target NET 4.X and .NET Core
  • Split Core project into Stuntman.Core and Stuntman.OWIN
  • Add Stuntman.AspNetCore project

In terms of having a single sample project demonstrating both OWIN and ASP.NET Core, that would be nice to keep all in one project, but I feel like it may be more confusing for people wanting to actually use the package. It might not be obvious to some that it's an either/or thing.

It would be nice to keep a single NuGet package, rather than have different one's targeting OWIN and ASP.NET Core.

Is that a possibility?

You could, yeah, but I think by definition that would require you to pull in dependencies for both OWIN and ASP.NET Core.

If you're using OWIN with ASP.NET 4.X or using ASP.NET Core like usual, then you're going to have a load of unneeded dependencies you need to pull into your application that you're not actually using.

Perhaps there's a way to create a single package and only bring in the dependencies the target needs (depending if it's targeting ASP.NET Core or not).

Looking at https://blogs.msdn.microsoft.com/cesardelatorre/2016/06/28/running-net-core-apps-on-multiple-frameworks-and-what-the-target-framework-monikers-tfms-are-about/ it looks like this might be possible with "imports" in project.json per the second summary bullet -- but, isn't that going away?

Although, maybe that doesn't work if you're constructing a NuGet package? πŸ˜ƒ

While that works for targeting both .NET 4.X and .NET Core, I don't think there's a way to target 'traditional' ASP.NET vs ASP.NET Core (the web framework as opposed to the underlying target framework). ASP.NET Core is just a nuget package added to your .NET console app after all.

It is possible to target full framework (.NET 4.x) and Core framework in one single nuget package.

Check out this example of a working nuspec for IdentityModel (which is a library consumed by IdentityServer).

Hi @kdaveid, yep that's definitely possible, the reason for 2 packages is to split out the OWIN middleware implementation vs the ASP.NET Core middleware. Both of those packages would support both Full and Core frameworks.

@khalidabuhakmeh, I've been running into some issues trying to get the OWIN version running on ASP.NET Core. Although you can do that using the Microsoft.AspNetCore.Owin package, it still doesn't support the OWIN IAppBuilder, it just directly wraps a Func<IDictionary<string, object>, Task>, which is causing me some pain!

I can't currently see an easy way to support both approaches, so I'm wondering if it's worth the effort? How many people are really going to use the OWIN wrapper on ASP.NET Core when there is a native version available, and OWIN is actively discouraged in that setting?

That way we would have

  • Stuntman.OWIN -> OWIN implementation, identical current samples (global.asax etc), Full framework
  • Stuntman.AspNetCore -> ASP.NET Core implementation, similar samples but ASP.NET Core, .NET Core + Full Framework.

Hello Andrew,

How many people are really going to use the OWIN wrapper on ASP.NET Core when there is a native version available, and OWIN is actively discouraged in that setting?

Yeah I wouldn't worry about supporting OWIN in ASP.NET Core just because that is something we'll probably be away from in the next year or two.

When you say, Owin Implementation and ASP.NET Core, I'd like the majority of the code to be shared as much as possible. So that any new feature would make its way into both packages.

You could use a Shared Project for anything that belongs in both projects. That functions like a class library but compiles as if it was in the project so there's no extra dll.

Cool, sounds good.

Unfortunately it looks like shared projects aren't supported with xproj, but we should be able to achieve something similar using project.json (see here).

More pain - I can't see a way of creating a global.asax based project that uses xproj, and we cannot reference a xproj-based projects from a global.asax based project that uses csproj.

Which means converting the OWIN pipeline Core project to xproj causes more problems than it solves.

I'm struggling to find a solution to the problem to be honest. I started down the root of keeping the current sln as-it and just adding the additional projects, but the Compile/include approach linked above using project.json doesn't work that well. The files aren't shown in the solution, they're just packaged in at build time, so you don't get any intellisense when working with them.

The actual conversion to ASP.NET Core isn't that tricky from what I've played with, it's just trying to keep the OWIN version intact that's causing the problems.. May have to bow out until the tooling improves/evolves and we get the ability to cross reference csproj/xproj more easily, sorry 😞

Hey could you submit a [WIP] PR so we can see what problems you are running into?

Sure, it's in #126

@andrewlock I think you're on the right path. Perhaps we could use Automapper as an example, and add common files to both projects as links instead of via a shared project?

The trouble with links in the xproj project is the files don't show in the solution, unlike the csproj style linked files... It will work, but it will mean the projects are no fun to work with when you start having to add compiler directives in etc for errors that you can't see until build time!

Having said that, I'll fire up the AutoMapper repo in the morning and check out how they do it in case I'm missing something obvious.

We could add the files under a solution folder so they are visible inside visual studio?

We could, but they still wouldn't show in the xproj project, so I don't think you would get intellisense etc.

Just had a thought actually, we leave the owin project as a csproj, and we move the files to the aspnetcore xproj project.

That way the aspnetcore project is just a normal xproj project (no project.json includes) , so you get proper intellisense, compiler directive support etc.

We can that add the same files as links to the csproj owin project as @jrusbatch suggested which should work well. That should do the trick! πŸ˜„

I've just pushed up a new branch which I think is a good start on the ASP.NET Core support. It doesn't have all the build or package steps sorted yet, but the Core project is converted, the test project is converted, and there are 2 sample applications. Functionally everything seems to work as expected:smile: