Skip to content

Latest commit

 

History

History
171 lines (131 loc) · 4.17 KB

Gen-Decor.md

File metadata and controls

171 lines (131 loc) · 4.17 KB

Usage

//注意 AutoDecor和AutoDecorFor是想反的标注,一个标注于需要装饰的类型上,一个标注于装饰器上

//标注于需要装饰的类型上

//netstandard2.0 +
[AutoDecor(Type implement)]

//C#11(NET7+) support generic attribute
[AutoDecor<T>]


//标注于装饰器上

//netstandard2.0 +
[AutoDecorFor(Type forType)]

//C#11(NET7+) support generic attribute
[AutoDecorFor<T>]

Define Base Service (IService or Class) & mark [AutoDecor]

  • 请注意,如需要避免代码侵入,可以使用partial拆分业务代码和特性
    [AutoDecor(typeof(HelloServiceDecor1))]
    [AutoDecor<HelloServiceDecor2>]
    public partial interface IHelloService
    {
        string SayHello(string name);
    }

    public class HelloService : IHelloService
    {
        public string SayHello(string name)
        {
            return $"Hello {name}";
        }
    }

    /// <summary>
    /// ClassService
    /// </summary>
    [AutoDecor<ClassServiceDecor>]
    public partial class ClassService
    {
        /// <summary>
        /// 请注意,如果TService是一个类,而不是interface,这里的virtual关键字是必须的
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public virtual string SayHello(string name)
        {
            return $"Hello {name}";
        }
    }

    public class ClassServiceDecor : ClassService
    {
        private readonly ClassService _helloService;
        private readonly ILogger<ClassServiceDecor> _logger;

        public ClassServiceDecor(ClassService helloService, ILogger<ClassServiceDecor> logger)
        {
            _helloService = helloService;
            _logger = logger;
        }

        public override string SayHello(string name)
        {
            Console.WriteLine($"Hello {name} from ClassServiceDecor");
            var result = _helloService.SayHello(name);
            _logger.LogInformation($"Hello {result} from ClassServiceDecor");
            return result;

        }
    }

    /// <summary>
    /// decor IHelloService
    /// </summary>
    public class HelloServiceDecor1 : HelloService
    {
        private readonly HelloService _helloService;

        public HelloServiceDecor1(HelloService helloService)
        {
            _helloService = helloService;
        }

        public new string SayHello(string name)
        {
            Console.WriteLine($"Hello {name} from HelloServiceDecor1");
            return _helloService.SayHello(name);
        }
    }

    /// <summary>
    /// decor IHelloService 2
    /// </summary>
    public class HelloServiceDecor2 : IHelloService
    {
        private readonly IHelloService _helloService;

        public HelloServiceDecor2(IHelloService helloService)
        {
            _helloService = helloService;
        }

        public string SayHello(string name)
        {
            Console.WriteLine($"Hello {name} from HelloServiceDecor2");
            return _helloService.SayHello(name);
        }
    }

auto generated

// <auto-generated />
#pragma warning disable
namespace Microsoft.Extensions.DependencyInjection
{
    public static class AutoDecorExtensions
    {
        /// <summary>
        /// AddAutoDecor
        /// </summary>
        public static IServiceCollection AddAutoDecor(this IServiceCollection services)
        {
            services.Decorate<TestConsole.Decors.IHelloService, TestConsole.Decors.HelloServiceDecor1>();
            services.Decorate<TestConsole.Decors.IHelloService, TestConsole.Decors.HelloServiceDecor2>();
            services.Decorate<TestConsole.Decors.ClassService, TestConsole.Decors.ClassServiceDecor>();
            return services;
        }
    }
}
#pragma warning restore

enjoy

// add services
builder.Services.AddScoped<IHelloService, HelloService>();
builder.Services.AddScoped<ClassService>();

// add auto decor
builder.Services.AddAutoDecor();

// get service

var helloService = builder.Services.GetRequiredService<IHelloService>();
var classService = builder.Services.GetRequiredService<ClassService>();

Report Diagnostic Code

  • GEN043: 标记[AutoDecor]的类型,装饰器必须是它的实现类或者子类