Я реализовал TimeProvider в большом приложении C #, чтобы обеспечить централизованный контроль времени приложения. В будущем я хочу убедиться, что никто не использует DateTime.Now/Today/UtcNow
, поскольку это обойдёт ранее упомянутую реализацию. Вместо этого я хочу, чтобы анализатор предложил использовать мой TimeProviderService
, чтобы он не пропускался, например, при проверке кода.
Я хочу решить эту проблему с помощью анализатора, поэтому мой вопрос: какЯ делаю это?
Ниже приведена одна из моих попыток;однако, этот, кажется, вызывает некую унаследованную проблему с FxCop:
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class Analyzer : DiagnosticAnalyzer
{
public override void Initialize(AnalysisContext context)
{
context.RegisterSyntaxNodeAction(AnalyzeSymbol, SyntaxKind.IdentifierName);
}
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; }
public static string DiagnosticId = "1337";
private static void AnalyzeSymbol(SyntaxNodeAnalysisContext context)
{
var token = context.Node.GetFirstToken();
if (token.ToString().Equals("DateTime"))
{
var nextToken = token.GetNextToken();
if (nextToken.IsKind(SyntaxKind.DotToken))
{
var dateTimeProperty = nextToken.GetNextToken();
var descripter = new DiagnosticDescriptor(DiagnosticId, "DateTime.Today: Use the TimeProvider.Today instead", "", "Noitso best practise", DiagnosticSeverity.Error, isEnabledByDefault: true);
if (dateTimeProperty.ToString().Equals("Now"))
{
context.ReportDiagnostic(Diagnostic.Create(descripter, context.Node.GetLocation(), "DateTime.Now: Use the TimeProvider.Now instead"));
}
else if (dateTimeProperty.ToString().Equals("Today"))
{
context.ReportDiagnostic(Diagnostic.Create(descripter, context.Node.GetLocation()));
}
else if (dateTimeProperty.ToString().Equals("UtcNow"))
{
context.ReportDiagnostic(Diagnostic.Create(descripter, context.Node.GetLocation(), "DateTime.UtcNow: Use the TimeProvider.UtcNow instead"));
}
}
}
}
}