c# - 避免非只读静态字段 - 不变性 NDepend
问题描述
我正在使用 NDepend 进行代码分析并收到此警告:
https://www.ndepend.com/default-rules/NDepend-Rules-Explorer.html?ruleid=ND1901#!
此规则警告未声明为只读的静态字段。
在面向对象编程中,保存可修改状态的自然工件是实例字段。这种可变的静态字段会在运行时对预期状态造成混淆,并损害代码的可测试性,因为每个测试都重复使用相同的可变状态。
我的代码如下:
using Cosmonaut;
using Microsoft.Azure.Documents.Client;
using System.Configuration;
using LuloWebApi.Entities;
namespace LuloWebApi.Components
{
/// <summary>
/// Main class that encapsulates the creation of instances to connecto to Cosmos DB
/// </summary>
public sealed class CosmosStoreHolder
{
/// <summary>
/// Property to be initiated only once in the constructor (singleton)
/// </summary>
private static CosmosStoreHolder instance = null;
/// <summary>
/// To block multiple instance creation
/// </summary>
private static readonly object padlock = new object();
/// <summary>
/// CosmosStore object to get tenants information
/// </summary>
public Cosmonaut.ICosmosStore<SharepointTenant> CosmosStoreTenant { get; }
/// <summary>
/// CosmosStore object to get site collection information
/// </summary>
public Cosmonaut.ICosmosStore<SiteCollection> CosmosStoreSiteCollection { get; }
/// <summary>
/// CosmosStore object to get page templates information
/// </summary>
public Cosmonaut.ICosmosStore<PageTemplate> CosmosStorePageTemplate { get; }
/// <summary>
/// CosmosStore object to get pages information
/// </summary>
public Cosmonaut.ICosmosStore<Page> CosmosStorePage { get; }
/// <summary>
/// CosmosStore object to get roles information
/// </summary>
public Cosmonaut.ICosmosStore<Role> CosmosStoreRole { get; }
/// <summary>
/// CosmosStore object to get clients information
/// </summary>
public Cosmonaut.ICosmosStore<Client> CosmosStoreClient { get; }
/// <summary>
/// CosmosStore object to get users information
/// </summary>
public Cosmonaut.ICosmosStore<User> CosmosStoreUser { get; }
/// <summary>
/// CosmosStore object to get partners information
/// </summary>
public Cosmonaut.ICosmosStore<Partner> CosmosStorePartner { get; }
/// <summary>
/// CosmosStore object to get super administrators information
/// </summary>
public Cosmonaut.ICosmosStore<SuperAdministrator> CosmosStoreSuperAdministrator { get; }
/// <summary>
/// Constructor
/// </summary>
CosmosStoreHolder()
{
CosmosStoreSettings settings = new Cosmonaut.CosmosStoreSettings(ConfigurationManager.AppSettings["database"].ToString(),
ConfigurationManager.AppSettings["endpoint"].ToString(),
ConfigurationManager.AppSettings["authKey"].ToString());
settings.ConnectionPolicy = new ConnectionPolicy
{
ConnectionMode = ConnectionMode.Direct,
ConnectionProtocol = Protocol.Tcp
};
CosmosStoreTenant = new CosmosStore<SharepointTenant>(settings);
CosmosStoreSiteCollection = new CosmosStore<SiteCollection>(settings);
CosmosStorePageTemplate = new CosmosStore<PageTemplate>(settings);
CosmosStorePage = new CosmosStore<Page>(settings);
CosmosStoreRole = new CosmosStore<Role>(settings);
CosmosStoreClient = new CosmosStore<Client>(settings);
CosmosStoreUser = new CosmosStore<User>(settings);
CosmosStorePartner = new CosmosStore<Partner>(settings);
CosmosStoreSuperAdministrator = new CosmosStore<SuperAdministrator>(settings);
}
/// <summary>
/// Instance access, singleton
/// </summary>
public static CosmosStoreHolder Instance
{
get
{
lock (padlock)
{
if (instance == null)
{
instance = new CosmosStoreHolder();
}
return instance;
}
}
}
}
}
但是我不确定如何解决此警告。
解决方案
这是一个指南,而不是硬性规则。通常,非只读静态字段很难凭直觉了解。但是在这种情况下,您正在执行延迟延迟加载,因此... alock
和 mutate 确实是实现此目的的一种方法,而不会导致它过早加载。
所以一个务实的解决方法是:忽略/覆盖警告
然而,另一种方法是将字段移动到另一种只读类型,并依赖延迟的 .cctor 语义:
public static CosmosStoreHolder Instance {
[MethodImpl(MethodImplOptions.NoInlining)]
get => DeferredHolder.Instance;
}
private static class DeferredHolder {
internal static readonly CosmosStoreHolder Instance = new CosmosStoreHolder();
}
然后你甚至不需要锁语义(.cctor 为你处理)。
推荐阅读
- swift - 如何在 WatchOS 中使用背景视图填充整个 Button 区域?
- wso2 - WSO2 代理服务 XML Xpath
- amazon-cloudfront - 如何为 EC2 网站配置 route53 和 cloudfront
- python - Python中递归定义的超操作序列
- python - 在 Mac 上启动电子应用程序后,硒网络驱动程序挂起
- sql-server - SQL Server:始终加密(尝试在加密列中插入值时出现数据类型冲突错误)
- c++ - pthread 执行时间比顺序执行时间差
- aws-config - 为什么此 AWS Config 规则没有可用的结果?
- arduino-c++ - 对字符使用 XOR 作为简单的校验和;一个字符只是一个字节吗?
- linux - QEMU 中没有 buildroot 登录