我正在重构一些代码。我的项目中有很多使用相同数据的报告。例如,他们每个人都使用List<Product>
,它是通过数据库检索的。
到目前为止,我有重复的行,例如:
var products = MyDatabase.Products.ToList();
我想要一个带有静态属性的静态类,供我的报告使用。
我想在报告中添加最后一行,例如:
var products = MyStaticClass.Products;
我想一次加载此列表,并允许我的报告使用它,而不是每次不同的报告想要该列表时都引用数据库。
我已经读过这个,解决方案似乎是:
1)
public static List<Product> Products
{
get
{
return MyDatabase.Products.ToList();
}
}
2)
public static List<Product> Products { get; set;} = MyDatabase.Products.ToList();
3)
public static List<Product> Products = MyDatabase.Products.ToList();
4)
private static List<Product> _products;
public static List<Product> Products
{
get
{
return _products ??
( _products = MyDatabase.Products.ToList());
}
}
5。
private static Lazy<List<Product>> _products =
new Lazy<List<Product>>(() => MyDatabase.Products.ToList());
public static List<Product> Products
{
get { return _products.Value; }
}
据我了解,第一种情况在我每次访问MyDatabase.Products.ToList()
时都会调用,因此这不是您想要的行为。
第二个选项几乎与第一个类似。有什么区别吗?或者只是第一个的较新版本。
第三个选项意味着只调用一次MyDatabase.Products.ToList()
,但是它将始终被调用,而与实际用法无关。关闭,我想。
第4个或第5个选项是否优于上述选项? Lazy<T>
是我的最佳选择吗?它只会在被调用时(如果被调用)加载数据吗?
请说明我是否正确理解了这些选项,并为我提供了理想的解决方案。
答案 0 :(得分:2)
这是您做过的最糟糕的决定:C#是一种面向对象的编程,即使在其他范例中,它也听起来像是一种设计气味。
因此,您想在许多报告中共享一些数据:依赖注入怎么样?设计您的类,以便能够注入共享数据:
public class Report
{
public Report(List<Product> products /* other arguments */)
{
Products = products;
}
private List<Product> Products { get; }
}
许多人可以访问,修改它。现在,在方程式中添加一些线程/并行性,您将需要额外的精力和复杂性来同步全局状态的读/写操作。
此外,这也是内存泄漏的一种证明:这些引用在整个应用程序生命周期中都是有效的。
避免全局状态:接受依赖项注入。