需要两个单身实例

时间:2012-01-26 11:45:00

标签: c# design-patterns singleton

我不得不用B类扩展现有代码。现有代码在Library中使用单例。现在,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 个答案:

答案 0 :(得分:5)

不幸的是Singleton pattern在这里真的无法帮助你,因为这个模式专门用于在应用程序的生命周期内返回一个且只有一个实例。

单身人士对于像Logging这样的特定情况很有用,但是他们通常会被忽略,因为他们很难模拟,测试和扩展。

如果可能,我建议重构上面的代码以使用Inversion of Control Pattern和构造函数注入依赖项。这是通过创建一个接口来实现的,例如ILibrary并具有两个实现。

这些实现可以创建一次并存储,以在第三个帮助器类中模拟类似Singleton的行为。一个非常好的方法是在企业应用程序中使用Dependency Injection Container,它可以维护实例的生命周期(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();
}

答案 1 :(得分:2)

如果您的设计总是限于2个实例,则可以提供属性Library.SecondInstance

无论如何,你可能也想看看Multiton模式。

答案 2 :(得分:1)

DI容器在这些情况下非常方便。 A和B都依赖于Libraray实例。不是在这两个类中创建该实例,而是将依赖项注入其中。像Autofac这样的DI容器可以为您保持单个实例的生命周期,从而允许您自由地注入这些依赖项。

答案 3 :(得分:0)

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

对我来说有点可读