需要两个单身实例

Dun*_*ken 4 c# singleton design-patterns

我不得不用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();
}
Run Code Online (Sandbox Code Playgroud)

永远不会有另一个班级.所以两个实例就可以了.

Dr.*_*ABT 5

不幸的是,Singleton模式实际上无法帮助您,因为此模式专门设计为在应用程序的生命周期内返回一个且仅一个实例.

单身对于某些情况如Logging非常有用,但是它们通常被避免,因为它们很难被模拟,测试和扩展.

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

这些实现可以创建一次并存储,以在第三个辅助类中模拟类似Singleton的行为.一个非常好的方法是在企业应用程序中使用依赖注入容器,它维护实例的生命周期(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();
}
Run Code Online (Sandbox Code Playgroud)