Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Injecting a factory Func with ASP.NET Core DI

I'm trying to get something like this working:

public class FooService : IFooService {
    public FooService(Func<IBarService> barFactory) { ... }
}
public class BarService : IBarService, IDisposable { ... }

services.AddSingleton<IFooService, FooService>();
services.AddTransient<IBarService, BarService>();
services.AddSingleton<Func<IBarService>>(ctx => () => ctx.GetService<IBarService());

This works as far as resolving the BarService instance, but I can't figure out how to properly manage its lifetime. When I do this inside one of the members of FooService:

using (var bar = _barFactory())
{
    ...
}

I get an ObjectDispoedException:

System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.

However, if I just do var bar = _barFactory();, without the using statement, I have no way to signal to the DI container that I'm done with the instance, and it can be disposed.

What's the correct approach here?


(Side note: yes, I know that some will object that a singleton service should not be dependent on a transient service. That's not what's happening here; the singleton service is dependent on a singleton factory, that produces transient instances. The singleton then uses the transient service for one or two statements and then is done with it, so there should be no actual lifetime problems here.)

like image 652
Tomas Aschan Avatar asked Jul 03 '17 16:07

Tomas Aschan


Video Answer


1 Answers

As described in documentation:

The container will call Dispose for IDisposable types it creates. However, if you add an instance to the container yourself, it will not be disposed.

So just don't use using statement and all should be OK.

like image 126
Ilya Chumakov Avatar answered Sep 20 '22 02:09

Ilya Chumakov