.NET Core - Class configured in container with Addsingleton() needs to be a Singleton?

Asked

Viewed 45 times

1

A Web API application in . NET Core consumes a DLL in . NET Standard. DLL has a Foo class that depends on the Bar class:

class Foo
{
    private readonly IBar bar;
    
    public Foo(IBar bar)
    {
        this.bar = bar;
    }
}

Bar is not a Singleton (no private constructor and no .Getinstance()), but must have only one instance shared throughout the application:

class Bar : IBar
{
    public int Contador {get; set;}
}

To do so, the Web API container is configured as follows:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<IBar, Bar>();
}

Now a Web application in . NET Framework 4.6.1 also needs to consume this DLL. This application has no container configuration. Follow the questions:

  1. When instantiating the Foo class, how to ensure that the injected Bar class behaves like Singleton? The Bar class should have been implemented as Singleton from the start?
  2. Class injected via Addsingleton() needs to be a Singleton?
  3. The configuration of the Bar class in the Web API container, if it was a Singleton, would be as below?

public void Configureservices(Iservicecollection services) { services.Addsingleton<Ibar, Bar.Getinstance()>(); }

1 answer

1

  1. For the Bar class to behave like Singleton just use the method AddSingleton when configuring API services. You don’t need to create Getinstance in the private class or constructs this is automatically handled by the framework.

  2. The injected class via Singleton can be a "normal" class. You do not need to follow the Singleton standard as if you were doing it in your hand. Create the public constructor with any dependencies that need to be solved or not and the methods it contains. The lifetime of the object will be set when you are setting up the service using the different methods: AddSingleton, AddScoped, AddTransient

  3. To add as Singleton, do: services.AddSingleton<IBar, Bar>();. A single instance of this class will be created throughout the application time.

  • thanks for the answers! I understood that it is not necessary for a class to be Singleton to be configured by Addsingleton() in the container, the container itself is in charge of treating a common class as Singleton. Also, an important point of doubt, is how the Web Application, without owning an Ioc container, can reference the DLL and maintain the behavior of Singleton’s Bar class? The Web API has an Ioc container, but the Web Application does not.

  • You cannot use the Singleton standard to try to synchronize information between two different applications. Each dll will run within the scope of the application, can not access from outside. Only if you had another application in the middle doing this control.

  • There are two applications (Web Application and Web API) accessing a Class Library (DLL in .NET Standard), each in its context, one has nothing to do with the other. I don’t want them sharing information with each other. I want to know how to make the Web Application can use the DLL and the Bar class behave like Singleton, even without having an Ioc container in the Web Application.

  • If the Web App project does not have an Ioc like in Web Api projects, you can use any of the various packages that exist to manage dependency injection. (Simpleinjector, for example) It varies from the chosen framework to the form of implementation, but as a rule, it should not run too far from how it is done in the API project. Use the method that allows you to register the object as Singleton in the framework you chose to manage dependencies. If you don’t want to use a framework in this project, you can create a wrapper class in the standard Singleton that returns the class Bar

  • Um I think we’re getting to the point! Could you give an example of what this wrapper class would look like?

  • Of course, follow the code in Pastebin: https://pastebin.com/kMCQqP3J The bar class remains a "normal" class, without the Singleton standard, and can be used in the Ioc API by AddSingleton. It behaves like Singleton in the API but needs "help" to behave like Singleton without help from the dependency injection framework. The way to do this is by using a wrapper class. Give a search about wrapper class. Roughly speaking, it would be a class that exposes methods that are implemented elsewhere.

  • Thank you @Leandro Battochio! I think that settles it! Just one observation, the wrapper class must implement the Ibar interface so that it can be injected into the Foo class constructor. What do you think?

  • The wrapper class does not need to have all methods of the class Bar. Only return a single instance of Bar is not enough? What you can do, to make sure that the wrapper class will follow the interface contract, is to change the type of the variable mInstance of Bar for IBar. This way you will enjoy the abstraction of the interface as I think you want. You can define methods in the Wrapper class if you want to call some method IBar but add some logic before the original method, for example. Also change the GetInstance for IBar.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.