0

我正在尝试创建一个如下所示的 Singleton 类,该类MyRepository位于单独的 DAL 项目中。它给我带来了循环引用问题,因为GetMySingleTon()方法返回MySingleTon类并需要它的访问权限。同样,我需要在类MyRepository的构造函数中访问MySingleTon

  public class MySingleTon
  {
    static MySingleTon()
    {
      if (Instance == null)
      {
        MyRepository rep = new MyRepository();
        Instance = rep.GetMySingleTon();
      }
    }
    public static MySingleTon Instance { get; private set; }
    public string prop1 { get; set; }
    public string prop2 { get; set; }
  }

更新:我做错了。我认为不需要任何单身人士。现在,我在第三个项目中创建了一个具有静态属性的类,并且我设置它一次并在任何地方访问它。它现在解决了我的问题。

谢谢大家的回答。

4

4 回答 4

1

存储库不应返回单例对象,存储库用于访问数据而不返回单例对象。您的存储库本身可以是单例,但我不推荐它,也不建议使用存储库的类使用单例。在您拥有的代码中,存储库似乎需要了解所有混乱的“业务层”,关系应该只有一种方式。我会将其重写为:

public class MySingleTon
{
    private MySingleTon()
    {
       // You constructor logic, maybe create a reference 
       // to your repository if you need it
    }

    private static MySingleTon _instance;
    public static MySingleTon Instance { 
       get
       {
          if(_instance == null)
             _instance = new MySingleTon();
          return _instance;
       }
    }
    public string prop1 { get; set; }
    public string prop2 { get; set; }
}

我不推荐我的解决方案,但它应该可以解决您的问题。我推荐的是研究依赖注入和控制反转,因为您的设计似乎有点错误。看看NInject

编辑:另一件事,为什么你的单身人士有几个公开的属性?单例不应该公开属性,它应该只公开函数,并且应该主要在你有一个实用程序类Math或像记录器这样的真正单例时使用。

于 2010-12-30T11:08:02.487 回答
0

虽然,创建这样的类引入并不好,我不知道这背后的原因是什么。

但你可以做类似于下面的代码

创建一个名为 Public Interface 的项目,并使用要从 MyRepository 类公开的公共函数定义一个接口 IMyRepository。

在返回 IMyRepository 的单例类中创建一个公共属性,也可以在程序集之外设置。

现在,您需要从引用您的单例程序集的程序集中显式设置此属性,并且我假设您可以从其他程序集创建 MyRepository 类的对象。

请注意:以上解决方案只是打破循环引用的技巧,而不是最佳解决方案。

于 2010-12-30T10:50:11.960 回答
0

虽然在类本身中拥有单例访问器属性是一种常用的快捷方式,但在更复杂的情况下,当您需要处理多个相关类的实例时,它可能证明是错误的方式。问题是在一个类中混合关注点。

您的MySingleton类应该是一些MyClass以通常不依赖于运行时存在的实例数量的方式实现的类。同样MyRepository应该能够管理和提供任意数量的MyClass实例。您将只处理一个单例实例的事实MyClass可以封装到一个单独的工厂(或访问器或任何您称之为的)类中,该类将绑定MyClassMyRepository在一起。

因此,尝试通过以下方式重新考虑您的设计(示意图):

public class MyClass { ... }

public class MyRepository
{
    public MyClass GetMyClassInstance(...);
}

public static class MyClassFactory
{
    public static MyClass SingletonInstance 
    { 
        get 
        { 
            if (singletonInstance == null) 
                singletonInstance = myRepository.GetMyClassInstance(...);
            return singletonInstance;
        }
    }
}

剩下的问题是myRepository从哪里来。例如,它可以在程序启动时创建并MyclassFactory作为成员字段提供。

归根结底,如果您考虑使用控制反转容器,很多事情都会变得更容易。下一步也是转向基于界面的设计。这为您提供了另一层抽象,并在实现的可互换性方面提供了更大的灵活性。

于 2010-12-30T10:51:01.093 回答
0

除了来自 Saurabh 的代码之外,您还将通过以下方式更改 Singleton 类:

public class MySingleTon
  {
    static MySingleTon()
    {
      if (Instance == null)
      {
        Instance = new MySingleTon();
      }
    }

    private MySingleTon(){}

    public static MySingleTon Instance { get; private set; }
    public IMyRepository MyRepository{ get; set ;}

  }
于 2010-12-30T10:54:09.970 回答