Comments (10)
I have been looking at @Gillardo's example more closely now and now understand where things go wrong. Gillardo is trying to move all of Openiddict's registrations into Simple Injector, but this is wrong, because:
- This is a very cumbersome practice,
- It can lead to hard to fix problems, since Openiddict classes might not be designed to work well with Simple Injector.
- Which might break any time a new version of Openiddict is released
Instead, you should always let Openiddict register itself in the default DI system and resolve one of its types when some application component needs to use it. You should refrain from trying to re-register every type of Openiddict into Simple Injector.
There are typically two practices you can apply. Either you 'cross-wire' the required type into Simple Injector -or- you create an adapter to an application-specified abstraction that resolves the OpenID type from the built-in DI container at runtime.
Cross-wiring is the concept of registering a delegate in one container so that it can resolve a type that is built-up by another container. We already see this concept of cross-wiring in Gillardo's code, but unfortunately Gillardo tries to register everything, instead of just cross-wiring that single type that needs to be injected by Simple Injector. So instead, we just want to do something like this:
container.RegisterSingleton<Func<DataProtectorTokenProvider<ApplicationUser>>>(
() => app.GetRequestService<DataProtectorTokenProvider<ApplicationUser>>());
The idea here is that if your application components only requires DataProtectorTokenProvider<ApplicationUser>
directly, this should be the only cross-wired registration you make. Since you typically have no idea about the lifestyle of such cross-wired service, it's best to register it as a Func<T>
factory; this way you won't get into any nasty problems like captive dependencies a.k.a. lifestyle mismatches. While captive dependencies are typically detected by Simple Injector, this is impossible to detect mismatches with cross-wired dependencies, since the Core DI doesn't contain the same safety nets as Simple Injector does and Simple Injector (nor you) doesn’t know about the actual lifestyle of the cross-wired component.
The GetRequestService
method is an extension method that is defined in the Missing-Core-DI-Extensions repository here. The Missing-Core-DI-Extensions is a repository I created to discuss some missing functionality in .NET Core with Microsoft. Hopefully these extension methods will end up in a future version of .NET Core, but for now you can copy paste this into your own application. The GetRequestService
method preserves the lifestyle of the registered instance, while calling app.ApplicationServices.GetService
does not (and can cause you major headackes because of that).
Instead of injecting a library type directly into your application components, I usually advice defining an application-specific abstraction. This way your application code stays oblivious to the library. This allows you to define an adapter implementation for this abstraction that wraps the IApplicationBuilder
and calls app.GetRequestService
when one of the adapter's methods is called. Such adapter can be registered as follows:
container.RegisterSingleton<IMyAppTokenProvider>(new AspNetTokenProvider(app));
Such adapter can be specified as follows:
public class AspNetTokenProvider : IMyAppTokenProvider
{
IApplicationBuilder app;
public AspNetTokenProvider(IApplicationBuilder app) { this.app = app; }
public string GetToken() {
var provider = this.app.GetRequestService<DataProtectorTokenProvider<ApplicationUser>>();
return provider. // etc
}
}
When using this practice, you can completely separate all the framework and library registrations (such as Openiddict’s) from your application registrations in Simple Injector and keep your Simple Injector registrations very clean, with just a few adapters or cross-wired registrations.
from openiddict-core.
I have tried to override everything, but doesnt seem to work. I have followed the code to actually create a OpenIddictProvider, which uses context.HttpContext.RequestServices which seems to always be the vNext DI. Am i missing something??
If you want to replace the default container offered by ASP.NET Core 1.0 (ex-ASP.NET 5), you need to update your ConfigureServices
method to return an IServiceProvider
instance calling your SimpleInjector container. Simply replacing specific services like the controller activator won't work (context.HttpContext.RequestServices
won't return your own container but the default one).
from openiddict-core.
This is not recommended by SimpleInjector, but i will ask them also and see what they say. Thanks
from openiddict-core.
Curious: why not using the built-in DI system?
Alternatively, you could use a DI provider that fully supports the new abstractions, like the great Autofac.
from openiddict-core.
I was using simpleinjector before going to vnext as it is far faster than autofac. The new aspnet DI i aimt convinced fully yet. I believe i have fixed this problem now as well without returning IServiceProvider and i will post here later encase others need to do it
from openiddict-core.
Plus i want to handle the creation of my services. I will let vnext resolve asp.net services, but not mine. Vnext DI also had limitations last time i checked
from openiddict-core.
Plus i want to handle the creation of my services. I will let vnext resolve asp.net services, but not mine. Vnext DI also had limitations last time i checked
This kind of hybrid thingy is not something we support (nor the rest of ASP.NET Core 1.0 does): if you don't want to use the recommended approach, you're sadly pretty much on your own.
from openiddict-core.
Curious: why not using the built-in DI system?
We (the Simple Injector team) advice against the use of an adapter on top of the new DI system, because this is an implementation of the Conforming Container anti-pattern and because such adapter is highly incompatible with Simple Injector. You can see an interesting discussion about me and Fowler here about why such adapter won't work for Simple Injector.
from openiddict-core.
@Gillardo did you ever find a working solution with OpenIddict and SimpleInjector?
from openiddict-core.
No I didn't. I ended up using the native DI instead
from openiddict-core.
Related Issues (20)
- 你好 请问OpenIddict 支持自定义授权码吗 我想通过框架本身的方法去生成授权码 看了很久的源码没找到 HOT 1
- Update `ValidateIdentityModelToken` to use `TryGetPayloadValue()` with `Dictionary<TKey, TValue>` instead of `ImmutableDictionary<TKey, TValue>`
- How to implement a custom OpenIddictClientEvents.HandleTokenResponseContext to handle related server-side prompt information. HOT 2
- Implement automatic expired token delete in db HOT 1
- ID0115 InvalidOperationException after upgrading to v4? HOT 2
- I want to make OpeniddictDbContext without inject it for other reasons HOT 1
- Why Just sponsors and contributors-only This Will Destory Openiddict Denude.IdentityServer Is Better HOT 3
- What's the OpenIddict stance for passkeys (WebauthN/FIDO2) support? HOT 6
- Config request: token endpoint called on different k8s pod than authorize endpoint, results in specified token is invalid (error ID2004) HOT 10
- Update the validation handler to support client assertions
- Make the allowed client authentication methods configurable
- MAUI App To Exchange Access Token (Google, Facebook, Apple, etc...) for openiddict generated JWT HOT 48
- Can I pass connect/token parameters via query strings? HOT 5
- Track future improvements to JSON support in Entity Framework Core
- Best way to implement Auth for Standalone Wasm + Asp Web Api HOT 4
- Audience Validation Issue HOT 1
- BadRequest when calling Userinfo endpoint with POST request HOT 3
- I have encountered error: invalid_request The 'iss' parameter cannot be used when 'authorization_response_iss_parameter_supported' is not supported by the authorization server. when adding new web provider based on IdentityServer HOT 11
- Azure B2C web provider integration HOT 6
- Introspection validation failure HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from openiddict-core.