DevTeam / Pure.DI

Pure DI for .NET
MIT License
410 stars 21 forks source link

Singleton Instance Not Shared for Multiple Interfaces #51

Closed ekalchev closed 2 months ago

ekalchev commented 2 months ago

I expect with the registration below to share the same instance of ServiceHost when resolving IServiceHost and IApplicationLifecycleManager. However I can see that two instances are created.

class ServiceHost : IServiceHost, IApplicationLifecycleManager
{
}
.Root<ServiceApplication>("Root")
            .Bind<Func<bool, ServiceHostEnvironment>>().To<Func<bool, ServiceHostEnvironment>>(ctx => (bool flag) => 
            {
                ctx.Inject(out Func<IServiceHost> serviceHostFactory);
                return new ServiceHostEnvironment(serviceHostFactory);
            })
            .Bind<IService>().To(ctx =>
            {
                ctx.Inject(out IApplicationLifecycleManager applicationLifecycleManager);
                return new StagingService(applicationLifecycleManager);
            })
            .Bind<Services.ServiceHost>().As(Singleton).To<Services.ServiceHost>()
            .Bind<IServiceHost>().To<Services.ServiceHost>()
            .Bind<IApplicationLifecycleManager>().To<Services.ServiceHost>()
            ;

If I change the last two lines to


            .Bind<IServiceHost>().To(ctx => 
            {
                ctx.Inject<Services.ServiceHost>(out var instance);
                return instance;
            })
            .Bind<IApplicationLifecycleManager>().To(ctx =>
            {
                ctx.Inject<Services.ServiceHost>(out var instance);
                return instance;
            })
            ;

It seems to be working as expected

NikolayPianikov commented 2 months ago

You have actually specified 3 different bindings here for Services.ServiceHost:

// 1
.Bind<Services.ServiceHost>().As(Singleton).To<Services.ServiceHost>()
// 2
.Bind<IServiceHost>().To<Services.ServiceHost>()
// 3
.Bind<IApplicationLifecycleManager>().To<Services.ServiceHost>()

But I assume you only wanted one:

.Bind<Services.ServiceHost, IApplicationLifecycleManager, IServiceHost>().As(Singleton).To<Services.ServiceHost>()

Or even simpler:

.Bind().As(Singleton).To<Services.ServiceHost>()
ekalchev commented 2 months ago

Thanks that worked!

NikolayPianikov commented 2 months ago

@ekalchev I saw that you are trying to use Func with arguments. Perhaps this example will help you :)