-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use in Web API #40
Comments
+1 |
This (Jab fully replacing the default DI) is something I would love to implement. But unfortunately there are two technical issues that stand in the way:
|
So while fully replacing the default service provider is hard short term I'll still try to think if there is any way to integrate them in a clean way. I'm also open to ideas of how you would like to see it. |
Hi Pavel... thanks for the reply! I have no doubt that it's well beyond my current knowledge to understand how it all works under the covers. As far as ideas on how we would see it (at least for the environment logic)...
So Jab would generate the injection code for all 3 scenarios (development, integration, default) and use the appropriate injection based on the current running environment at runtime. A "default" (no environment specified) would be required (build would fail without it) to cover any environments not listed. Just my thoughts. Thanks again for the response! |
Maybe you could have a look at https://github.com/YairHalberstadt/stronginject/tree/main/Samples/AspNetCore .. it's a similar solution to yours, and someone managed to workaround ASP.NET controllers dependency injection. I would like even to have a look myself at it when I'm a little more free, but right now I don't have time... maybe in 15 days I can have a look at it... if I can apply the same solution as theirs I would make a PR for you ;) |
The linked approach has a problem: now you have 2 DI containers managing the same set of objects causing problems like multiple disposal. It also makes it hard to resolve outer DI services from the source generated container. I have a branch where I try to marry Microsoft.Extensions.DependencyInjection with Jab and make them aware of each other and cooperating. It's very much WIP but might result in something interesting. |
Just chucking out some ideas:
I think if you wanted to instead build a jab container for all of the asp.net core dependencies it would be a lot of work to figure out the various runtime conditions like environment or config checks like you have mentioned. Another approach:
Forgive me if you've already established a way forward with this! |
AutoFaq can also consume Microsoft's DI. I agree that not everything needs to be compile-time. |
Any update on this? Just discovered this project and I like the concept. Though like others backend work is my bread and butter and honestly that's where the perf gains are most useful, don't really care too much about saving a few ns on a client, but on the server that = $$ saved. |
I made a prototype integration with Microsoft.Extensions.DependencyInjection: https://github.com/R2D221/Jab.MediIntegration/blob/master/WebApplication1/MyServiceProvider.Medi.cs It may be rough and not optimized beyond the obvious, but for the moment I think it gets the job done. Essentialy what I made was the following:
I don't know if this still aligns with the spirit of the project, but I think this could be useful to be able to handle the dynamic nature of Microsoft.Extensions.DependencyInjection while still allowing us to add our compile-time dependencies. If you'd want to refine this and include it officially in the project, I'd be happy to help. Even if not, I'm happy to share my solution with anyone who needs it. |
For anyone who thinks that the answer ought to be simpler than @R2D221's integration above, perhaps even as simple as using For example, you won't be able to constructor-inject any of your controllers with Jab stuff, because the thing that resolves controllers will live within the So in effect you have to duplicate the functionality of A very rough and hacky alternative is to just re-register all the Jab services into Microsoft's using System.Linq.Expressions;
using Jab;
using Microsoft.Extensions.DependencyInjection;
static class ServiceCollectionExtensions
{
public static void AddJabServices(this IServiceCollection serviceCollection, object services)
{
foreach (var iface in services.GetType().GetInterfaces())
{
if (!iface.IsGenericType)
continue;
var genericType = iface.GetGenericTypeDefinition();
if (genericType != typeof(IServiceProvider<>))
continue;
var getServiceMethod = iface.GetMethod(nameof(IServiceProvider<object>.GetService)) ?? throw new Exception("Cannot find the method");
var serviceType = iface.GetGenericArguments().Single();
var servicesParameter = Expression.Parameter(typeof(object));
var getService = Expression.Lambda<Func<object, object>>(
Expression.Convert(
Expression.Call(
Expression.Convert(
servicesParameter,
iface
),
getServiceMethod
),
typeof(object)
),
servicesParameter
).Compile();
serviceCollection.AddTransient(
serviceType,
_ => getService(services)
);
}
}
} var builder = WebApplication.CreateBuilder();
builder.Services.AddJabServices(services); // services is an instance of your Jab services class |
Just saw a demo of this on YouTube (shoutout to Nick Chapsas... love his channel!) and it looks very interesting! However, 95% of what I do is in a web API. Do you have plans to support a clean way of using Jab in a web API? I could use the default DI to inject my Jab "service provider" into controllers/classes and request what I need from there, but that's not a clean solution IMO.
The text was updated successfully, but these errors were encountered: