Нужны два экземпляра синглтона - PullRequest
4 голосов
/ 26 января 2012

Мне пришлось расширить свой существующий код с помощью класса B. В существующем коде используется библиотека Singleton.Теперь для класса B (который сам будет доступен как одиночный, как и класс A) нужен собственный экземпляр библиотеки ...

Мне интересно, как лучше всего расширить существующий код (Класс A, Библиотека)так что мне нужно изменить библиотеку как можно меньше.

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();
}

Никогда не будет другого класса.Таким образом, два экземпляра будут в порядке.

Ответы [ 4 ]

5 голосов
/ 26 января 2012

К сожалению, шаблон Singleton действительно не может вам здесь помочь, так как этот шаблон специально предназначен для возврата одного и только одного экземпляра за время существования приложения.

Синглтоны полезны в некоторых случаях, таких как ведение журнала, однако их обычно избегают, поскольку общеизвестно, что их трудно макетировать, тестировать и расширять.

По возможности яРекомендую рефакторинг приведенного выше кода для использования Инверсия шаблона управления и конструктор внедрения зависимости.Это достигается созданием интерфейса, скажем, ILibrary и наличием двух реализаций.

Эти реализации могут быть созданы один раз и сохранены для эмуляции Синглтоноподобного поведения в третьем вспомогательном классе.Действительно хороший способ сделать это в корпоративном приложении - это использовать Контейнер внедрения зависимостей , который поддерживает время жизни экземпляров (Singleton или Transient) и позволяет легко внедрять их в конструкторы.

Пример кода с использованием IoC / DI в качестве шаблона будет выглядеть следующим образом:

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();
}
2 голосов
/ 26 января 2012

Если ваш дизайн всегда будет ограничен 2 экземплярами, вы можете предоставить свойство Library.SecondInstance.

В любом случае, вы также можете взглянуть на шаблон Multiton.

1 голос
/ 26 января 2012

DI контейнер очень удобен в этих случаях.И A, и B зависят от экземпляра Libraray.Вместо того чтобы создавать этот экземпляр в этих двух классах, добавьте к ним зависимость.Контейнеры DI, такие как Autofac, поддерживают время жизни одного экземпляра, что позволяет свободно вводить эти зависимости.

0 голосов
/ 26 января 2012
 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!!
    }

использование

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

выглядит немного читабельным для меня

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...