我正在尝试创建一个类似下面的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; }
}
更新:我做得非常错误。 我认为不需要任何单身人士。现在我在第三个项目中创建了一个具有静态属性的类,我将它设置一次并随处访问它。它现在解决了我的问题。
感谢大家的回答。
答案 0 :(得分: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
这样的实用程序类或像记录器这样的真正单例时使用。
答案 1 :(得分:0)
虽然,创建这样的类内部并不好,但我不知道这背后的原因是什么。
但您可以执行类似下面的代码
创建一个名为Public Interface的项目,并使用要从MyRepository类公开的公共函数定义一个接口IMyRepository。
在单例类中创建一个返回IMyRepository的公共属性,也可以在程序集外部设置。
现在,您需要从引用singelton程序集的程序集中显式设置此属性,并假设您可以从其他程序集创建MyRepository类的对象。
请注意:上述解决方案只是打破循环引用而不是最佳解决方案的技巧。
答案 2 :(得分:0)
虽然在类本身中具有单例访问器属性是一种通常使用的快捷方式,但在更复杂的情况下,当您需要处理多个相关类的实例时,它可能证明是错误的方式。问题在于将问题混合在一个类中。
您的MySingleton
类应该是某些MyClass
,其实现方式通常不依赖于运行时存在的实例数。同样,MyRepository
应能够管理并提供任意数量的MyClass
个实例。您将只处理MyClass
的单个实例的事实可以封装到一个单独的工厂(或访问器或任何您称之为)的类中,它将MyClass
和MyRepository
绑定在一起。
因此,请尝试以下列方式重新考虑您的设计(原理图):
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
。
在一天结束时,如果考虑使用控制容器的反转,可以使很多事情变得容易。下一步也将转向基于接口的设计。这为您提供了另一层抽象,并在实现的可互换性方面提供了更大的灵活性。
答案 3 :(得分: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 ;}
}