Сообщение Aspect Generator (по мотивам "Новости C#12") от 22.11.2023 3:05
Изменено 22.11.2023 3:07 IT
Aspect Generator (по мотивам "Новости C#12")
В данном
В качестве подтверждения того, что это не так предлагаю взглянуть на проект, где это уже в определённой степени реализовано и некоторым образом работает.
По сути это реинкарнация аспектов из BLToolkit, кроме реализации самих аспектов. Сами аспекты предлагается реализовывать пользователям, т.к. с этим генератором это делается максимально просто (хотелось в это верить).
Пример для OpenTelemetry:
Пример использования:
Автор: Serginio1
Дата: 13.04.23
топике народ обсуждает новую экспериментальную фичу C# — Interceptors. При этом некоторые коллеги выразили сомнения, что это фича рабочая в частности для AOP.Дата: 13.04.23
В качестве подтверждения того, что это не так предлагаю взглянуть на проект, где это уже в определённой степени реализовано и некоторым образом работает.
По сути это реинкарнация аспектов из BLToolkit, кроме реализации самих аспектов. Сами аспекты предлагается реализовывать пользователям, т.к. с этим генератором это делается максимально просто (хотелось в это верить).
Пример для OpenTelemetry:
using System;
using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace Aspects
{
/// <summary>
/// Initializes OpenTelemetry.
/// </summary>
static class OpenTelemetryFactory
{
public static TracerProvider? Create()
{
return Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
.AddSource("Sample.Aspect")
.AddConsoleExporter()
.Build();
}
}
/// <summary>
/// Metrics aspect.
/// </summary>
[Aspect(
OnUsing = nameof(OnUsing),
OnFinally = nameof(OnFinally)
)]
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
sealed class MetricsAttribute : Attribute
{
static readonly ActivitySource _activitySource = new("Sample.Aspect");
public static Activity? OnUsing(InterceptCallInfo info)
{
var activity = _activitySource.StartActivity(info.MemberInfo.Name);
info.Tag = activity;
return activity;
}
public static void OnFinally(InterceptCallInfo info)
{
if (info is { Tag: Activity activity, Exception: var ex })
activity.SetStatus(ex is null ? ActivityStatusCode.Ok : ActivityStatusCode.Error);
}
}
}Пример использования:
using System;
using System.Threading;
using Aspects;
namespace OpenTelemetryAspect
{
static class Program
{
static void Main()
{
using var _ = OpenTelemetryFactory.Create();
Method1();
Method2();
Method1();
try
{
ExceptionMethod();
}
catch
{
// ignored
}
}
[Metrics]
public static void Method1()
{
Thread.Sleep(100);
}
[Metrics]
public static void Method2()
{
Thread.Sleep(200);
}
[Metrics]
public static void ExceptionMethod()
{
throw new();
}
}
}Aspect Generator (по мотивам "Новости C#12")
В данном
В качестве подтверждения того, что это не так предлагаю взглянуть на проект, где это уже в определённой степени реализовано и некоторым образом работает.
По сути это реинкарнация аспектов из BLToolkit, кроме реализации самих аспектов. Сами аспекты предлагается реализовывать пользователям, т.к. с этим генератором это делается максимально просто (хотелось бы в это верить).
Пример для OpenTelemetry:
Пример использования:
Автор: Serginio1
Дата: 13.04.23
топике народ обсуждает новую экспериментальную фичу C# — Interceptors. При этом некоторые коллеги выразили сомнения, что это фича рабочая в частности для AOP.Дата: 13.04.23
В качестве подтверждения того, что это не так предлагаю взглянуть на проект, где это уже в определённой степени реализовано и некоторым образом работает.
По сути это реинкарнация аспектов из BLToolkit, кроме реализации самих аспектов. Сами аспекты предлагается реализовывать пользователям, т.к. с этим генератором это делается максимально просто (хотелось бы в это верить).
Пример для OpenTelemetry:
using System;
using System.Diagnostics;
using OpenTelemetry;
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
namespace Aspects
{
/// <summary>
/// Initializes OpenTelemetry.
/// </summary>
static class OpenTelemetryFactory
{
public static TracerProvider? Create()
{
return Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(ResourceBuilder.CreateDefault().AddService("MySample"))
.AddSource("Sample.Aspect")
.AddConsoleExporter()
.Build();
}
}
/// <summary>
/// Metrics aspect.
/// </summary>
[Aspect(
OnUsing = nameof(OnUsing),
OnFinally = nameof(OnFinally)
)]
[AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
sealed class MetricsAttribute : Attribute
{
static readonly ActivitySource _activitySource = new("Sample.Aspect");
public static Activity? OnUsing(InterceptCallInfo info)
{
var activity = _activitySource.StartActivity(info.MemberInfo.Name);
info.Tag = activity;
return activity;
}
public static void OnFinally(InterceptCallInfo info)
{
if (info is { Tag: Activity activity, Exception: var ex })
activity.SetStatus(ex is null ? ActivityStatusCode.Ok : ActivityStatusCode.Error);
}
}
}Пример использования:
using System;
using System.Threading;
using Aspects;
namespace OpenTelemetryAspect
{
static class Program
{
static void Main()
{
using var _ = OpenTelemetryFactory.Create();
Method1();
Method2();
Method1();
try
{
ExceptionMethod();
}
catch
{
// ignored
}
}
[Metrics]
public static void Method1()
{
Thread.Sleep(100);
}
[Metrics]
public static void Method2()
{
Thread.Sleep(200);
}
[Metrics]
public static void ExceptionMethod()
{
throw new();
}
}
}