Search code examples
c#.net-coreasp.net-core-2.0

Updating a dependency injected singleton


I generate a singleton at runtime

public void ConfigureServices(IServiceCollection services)
{
    var applications = Utils.generateApplications()
    services.AddSingleton<ApplicationModel[]>(applications);
    services.AddMvc();
}

How can I later update this dependency injected ApplicationModel[] with a completely new ApplicationModel[]. I have a feature in my application that the user can use to trigger a data refresh on the applications, but how can I update the underlying injected Singleton so all future injections will use the updated applications? I have a function Utils.generateApplications() that gets an up to date list of applications and returns a ApplicationModel[]. How do I overwrite the old injected Singleton with a new object to be injected into future calls if that makes sense?

I have some code :

public void UpdateData()
{
    var applications = Utils.generateApplications()
    //How do I set applications to replace the injected singleton for all future injections?
}

Solution

  • I wouldn't monkey with dependency injection that way. Instead, inject a factory, and write whatever logic you need to return the proper instance.

    Simple factory:

    interface IApplicationModelFactory
    {
        ApplicationModel[] Model { get; }
    }
    
    class ApplicationModelFactory : IApplicationModelFactory
    {
        public ApplicationModel[] Model { get; set; }
    }
    

    Registration:

    services.AddSingleton<IApplicationModelFactory>
    (
        new ApplicationModelFactory[] { Model = util.generateApplications() }
    )
    

    class receiving the injection:

    class Foo
    {
        protected readonly IApplicationModelFactory _factory;
    
        public Foo(IApplicationModelFactory injected)
        {
            _factory = injected;
        }
    
        protected ApplicationModel[] => _factory.Model;
    
        public void Bar()
        {
            DoSomethingWithModel(this.ApplicationModel);
        }
    }