Requires two instances of a singleton

I had to extend existing code with class B. Existing code uses a singleton in the library. Now class B (which itself will be available as singleton, as class A) needs its own library instance ...

I am wondering what is the best way to extend existing code (class A, library) so that I can change the library as little as possible.

public class A { var lib = Library.Instance; public DoSomething() { lib.DoStuff(); } } public class B { var lib = Library.Instance; //wrong! needs its own instance public DoSomething() { lib.DoOtherStuff(); } } public class Library { public static Library Instance { get { return _librarySingleton; } } //library internally uses singleton too!! } public static class MyProgram { var a = new A(); //will be an singleton var b = new B(); //will be an singleton a.DoSomething(); b.DoSomething(); } 

There will be no other class. So two instances will be fine.

+4
source share
4 answers

Unfortunately, the Singleton pattern really cannot help you here, since this template is specifically designed to return one and only one instance for the whole life of the application.

Singletones are useful for some cases, such as Logging, but they are usually avoided because they are known to be difficult to mock, test, and distribute.

If possible, I would recommend refactoring the above code using Inversion of Control Pattern and constructor dependency injection. This is achieved by creating an interface, say ILibrary , which has two implementations.

These implementations can be created once and saved to emulate behavior similar to Singleton in a third helper class. A good way to do this in a corporate application is to use a dependency injection container that supports instance lifetimes (Singleton or Transient) and makes it easy to inject into constructors.

Sample code using IoC / DI as a template will look like this:

 public class A { private readonly ILibrary _library; public A(ILibrary library) { _library = library; } public DoSomething() { _library.DoStuff(); } } public class B { private readonly ILibrary _library; public B(ILibrary library) { _library = library; } public DoSomething() { _library.DoStuff(); } } public interface ILibrary { void DoStuff(); } public class LibraryTypeOne : ILibrary { void DoStuff() { Console.WriteLine("I am library type one"); } } public class LibraryTypeTwo : ILibrary { void DoStuff() { Console.WriteLine("I am library type two"); } } public static class MyProgram { var a = new A(new LibraryTypeOne()); // Note, you need to store var b = new B(new LibraryTypeTwo()); // these instances somewhere to // share throughout the app a.DoSomething(); b.DoSomething(); } 
+5
source

If your project will always be limited to two instances, you can provide the Library.SecondInstance property.

In any case, you can also take a look at the Multiton template.

+2
source

The DI container is very convenient in these cases. Both A and B depend on the Libraray instance. Instead of creating this instance in these two classes, enter a dependency on them. DI containers like Autofac maintain a single lifetime for you, allowing you to freely enter these dependencies.

+1
source
  public class Library { public Library() { } private static Library _secondInstance = new Library(); private static Library _librarySingleton = new Library(); public Library Second() { return _secondInstance; } public static Library Instance { get { return _librarySingleton; } } //library internally uses singleton too!! } 

Using

  Library obj1 = Library.Instance; Library obj2= Library.Instance.Second(); 

Seems a little readable to me

0
source

Source: https://habr.com/ru/post/1393149/


All Articles