unitycontainer / microsoft-dependency-injection

Unity.Microsoft.DependencyInjection package
Apache License 2.0
63 stars 36 forks source link

Make Configuration.AddServices public #54

Open irontoby opened 5 years ago

irontoby commented 5 years ago

We have an existing ASP.NET (not Core) app which is using Unity container for DI. However we would like to add some new Microsoft services such as health checks which require an IServiceCollection to configure.

It would be very helpful if I could create a ServiceCollection, add the new Microsoft services, and then populate an existing Unity container with those services. (This seems to be the same request as #23 and/or #24 which were closed by the submitter w/o comment).

It looks like IUnityContainer AddServices(this IUnityContainer container, IServiceCollection services) in Configuration.cs does exactly this, but it's currently internal. Is there any reason to not make it public?

I can currently create a ServiceProviderFactory then call CreateBuilder but that does not allow me to re-use the Unity container I already have.

ENikS commented 5 years ago

Why don't you register these services with the container directly?

The collection is not necessarily and only adds overhead.

irontoby commented 5 years ago

For example, to set up Microsoft health checks it is necessary to call their extension method AddHealthChecks(this IServiceCollection services) (source code here). So I need an IServiceCollection interface to pass to that method. Their method in turn uses internal implementations of HealthCheckService and IHostedService so I cannot set those up directly.

I agree if I could just pass the container to that method it would be best, but I don't see any other way to do that. Is there a better way I'm missing?

ENikS commented 5 years ago

You might do in Config class in virtual override.

Adding a method to register more collections is trivial but I might not get to it until late September

cduivis commented 4 years ago

I'm facing the same issue, you've written an really nice library, with a really good structure. We currently have our own provider factory which partly makes use of this library, but was left on the 2.x version for various reasons.

Now that I'm upgrading from the 2.x to the version 5.x of this library, I'm noticing that I basically need to copy paste all the internal logic, just because I want to make use of the AddServices extension method of the Configuration class.

For which I would also need to copy paste the InjectionTransientLifetimeManager because it's class is set to internal (for which I created a PR btw : https://github.com/unitycontainer/microsoft-dependency-injection/pull/72).

ENikS commented 4 years ago

Could you provide me with a sample of how you want it to be used? Perhaps couple of different scenarios?

I'd like to make sure I understand it correctly.

cduivis commented 4 years ago

Our scenario has similar behavior as this packages use of Configuration.AddServices. But we are creating dependency injection for a multi-tenant environment, which requires us to write our own provider factory and provider. But for the normal defined dependencies we want to pass them along to Unity. Basically these which are typically defined in the Startup.cs:

services
    .AddScoped<IMyDependency, MyDependency>()
    .AddTransient<IOperationTransient, Operation>()
    .AddScoped<IOperationScoped, Operation>()
    .AddSingleton<IOperationSingleton, Operation>()
    .AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));

(As far as I can see that's the same way this package is using the Configuration.AddServices?)

And because you've already written that "plumbing" for this perfectly it would be a waste to rewrite the exact same behavior.

ENikS commented 4 years ago

What stops you from doing this?

public void ConfigureServices(IServiceCollection services)
{
    services
    .AddScoped<IMyDependency, MyDependency>()
    .AddTransient<IOperationTransient, Operation>()
    .AddScoped<IOperationScoped, Operation>()
    .AddSingleton<IOperationSingleton, Operation>()
    .AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
}

Unity supports normal initialization provided in Startup.cs

Patrickkk commented 3 years ago

What stops you from doing this?

public void ConfigureServices(IServiceCollection services)
{
    services
  .AddScoped<IMyDependency, MyDependency>()
  .AddTransient<IOperationTransient, Operation>()
  .AddScoped<IOperationScoped, Operation>()
  .AddSingleton<IOperationSingleton, Operation>()
  .AddSingleton<IOperationSingletonInstance>(new Operation(Guid.Empty));
}

Unity supports normal initialization provided in Startup.cs

When using this for non web applications such as console applications this would be usefull :)