C# Atrribute和反射, 工厂模式和依赖注入的简单例子

Attribute 需要以Attribute 结尾, 并继承Attribute



using AttributeTest;
using System.Reflection;

List<Type> heroTypes = new();
object selecthero;

//所有英雄的类型
heroTypes = Assembly.GetExecutingAssembly().GetTypes()
    .Where(t => t.GetCustomAttributes(typeof(HeroAttribute), false).Any()).ToList();


//英雄的名字
var list = heroTypes.Select(t => t.Name).ToList();

foreach (var item in list)
{
    Console.WriteLine(item);
}

Console.WriteLine("==============");
foreach (var item in heroTypes)
{
    var t = Activator.CreateInstance(item);//创建对象
    var skillMethods = item.GetMethods().Where(m =>
    m.GetCustomAttributes(typeof(SkillAttribute), false)
    .Any()).ToList();

    var methodsName = skillMethods.Select(m => m.Name).ToList();
    methodsName.ForEach(x => Console.WriteLine(x));
}

Console.WriteLine("======+++========");

Blademaster bm = new();

var prop1 = bm.GetType();
var prop2 = typeof(Blademaster);

Console.WriteLine(prop1);
Console.WriteLine(prop2);

Console.WriteLine("======ctor========");
var ctor1 = prop1.GetConstructor(new Type[0]); //获取无参ctor
var ctor2 = prop1.GetConstructor(new Type[] { typeof(string) });
var ctor3 = prop1.GetConstructor(new Type[] { typeof(string), typeof(string) });
Console.WriteLine(ctor1);
Console.WriteLine(ctor2);
Console.WriteLine(ctor3);


Console.WriteLine("======ctors========");
var ctors = prop2.GetConstructors();

foreach (var item in ctors)
{
    Console.WriteLine(item);
}



Student stu = new()
{
    Id = 1,
    Name = "TTT",
    Description = "DDD",
    Birthday = 555
}
;

Blademaster bm3 = new() 
{
    Name = "TTT",
     Height = "666",
     Race = "兽族"
};

var fileds = typeof(Student).GetFields(BindingFlags.NonPublic | BindingFlags.Instance |BindingFlags.Public );

Console.WriteLine("======GetFields========");
foreach (var item in fileds)
{
    Console.WriteLine(item.Name);

}
Console.WriteLine("======GetProperties========");
var fileds2 = typeof(Student).GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public);


foreach (var item in fileds2)
{
    Console.WriteLine(item.Name);
    Console.WriteLine(item.GetValue(stu));
}

Console.WriteLine("======GetMethods========");
var methods = typeof(Student).GetMethods();

foreach (var item in methods)
{
    Console.WriteLine(item.Name);
}

Console.WriteLine("======GetMembers========");

var members = typeof(Student).GetMembers();

foreach (var item in members)
{
    Console.WriteLine(item.Name);
}

//通过反射建立对象
Console.WriteLine("======通过反射建立对象========");
var obj = Activator.CreateInstance(bm3.GetType());

var pops = obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

foreach (var item in pops)
{
    Console.WriteLine(item.Name);
    Console.WriteLine(item.GetValue(bm3)); //item由反射来的属性,和对象没有关系,如果获得值,需要具体对象

    if (item.Name == "Race")
    {

    }
}



结果 :

Blademaster
==============
JiFengBu
ZhiMingYiJi
======+++========
AttributeTest.Blademaster
AttributeTest.Blademaster
======ctor========
Void .ctor()
Void .ctor(System.String)
Void .ctor(System.String, System.String)
======ctors========
Void .ctor(System.String)
Void .ctor()
Void .ctor(System.String, System.String)
======GetFields========
<Id>k__BackingField
<Name>k__BackingField
<Description>k__BackingField
<Age>k__BackingField
birthday
======GetProperties========
Id
1
Name
TTT
Description
DDD
Age
0
Birthday
555
======GetMethods========
get_Id
set_Id
get_Name
set_Name
get_Description
set_Description
get_Age
set_Age
get_Birthday
set_Birthday
GetType
ToString
Equals
GetHashCode
======GetMembers========
get_Id
set_Id
get_Name
set_Name
get_Description
set_Description
get_Age
set_Age
get_Birthday
set_Birthday
GetType
ToString
Equals
GetHashCode
.ctor
Id
Name
Description
Age
Birthday
======通过反射建立对象========
Name
TTT
Race
兽族
Height
666

工厂模式 webAPI应用

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
	  <PackageReference Include="Serilog" Version="3.0.1" />
	  <PackageReference Include="Serilog.AspNetCore" Version="6.1.0" />
	  <PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
	  <PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
	  <PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
  </ItemGroup>

</Project>

using MyWebApiTest.Service;
using MyWebApiTest.Service.Imp;
using Serilog;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.


//日志
builder.Host.UseSerilog((context, logger) =>
{
    logger.ReadFrom.Configuration(context.Configuration);
    logger.Enrich.FromLogContext();
});

// Add services to the container.
builder.Configuration.AddJsonFile("appsettings.json", false, true);
var cfg = builder.Configuration;
builder.Services.AddSingleton<IConfiguration>(cfg);


builder.Services.AddSingleton<IConnFactoryService, ConnFactoryServiceImpl>();

builder.Services.AddControllers();
builder.Services.AddCors(c => c.AddPolicy("any", p => p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseCors("any");

app.UseAuthorization();

app.MapControllers();

app.Run();

namespace MyWebApiTest.Service
{
    public interface IConnService
    {
        bool Conn { get; set; }

        void ReadClass();
    }
}

namespace MyWebApiTest.Service
{
    public interface IConnFactoryService
    {
        IConnService CreateConn();
    }
}

namespace MyWebApiTest.Service.Imp
{
    public class ConnServiceImpl2 : IConnService
    {
        private int i = 0;

        public ConnServiceImpl2(ILogger<IConnService> logger)
        {
            this.logger = logger;
        }
        private bool conn;
        private readonly ILogger<IConnService> logger;

        public bool Conn { get => conn; set => conn = value; }

        public void ReadClass()
        {
            i += 3;//每次递增, 调用同一个ConnServiceImpl2
            logger.LogInformation("ConnServiceImpl2在读取数据!@!");
            logger.LogInformation(i.ToString());
        }
    }
}



namespace MyWebApiTest.Service.Imp
{
    public class ConnServiceImpl1 : IConnService
    {
        private int i = 0;
        public ConnServiceImpl1(ILogger<IConnService> logger)
        {
            this.logger = logger;

        }
        private bool conn;
        private readonly ILogger<IConnService> logger;

        public bool Conn { get => conn; set => conn = value; }

        public void ReadClass()
        {
            i += 1;//每次递增, 调用同一个ConnServiceImpl1
            logger.LogInformation("ConnServiceImpl1在读取数据!!");
            logger.LogInformation(i.ToString());
            //Console.WriteLine("ConnServiceImpl1在读取数据!!");
        }
    }
}

namespace MyWebApiTest.Service.Imp
{
    public class ConnFactoryServiceImpl : IConnFactoryService
    {
        private readonly IConnService conn;
        private readonly ILogger<IConnService> logger;

        public ConnFactoryServiceImpl(ILogger<IConnService> logger)
        {
            this.logger = logger;
            this.conn = new ConnServiceImpl1(logger);
        }
        public IConnService CreateConn()
        {
            conn.ReadClass();
            return conn;
        }
    }
}

using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using MyWebApiTest.Service;

namespace MyWebApiTest.Controllers
{
    [Route("api/private/v1/[controller]/[action]")]
    [ApiController]
    [EnableCors("any")]
    public class MyTestController : ControllerBase
    {
        private readonly ILogger<MyTestController> logger;
        private readonly IConnFactoryService service;

        public MyTestController(ILogger<MyTestController> logger, IConnFactoryService service)
        {
            this.logger = logger;
            this.service = service;
        }

        [HttpGet]
        public void Test1()
        {
            service.CreateConn();
        }
    }
}

更换ConnServiceImpl1为ConnServiceImpl2时, 只需要

this.conn = new ConnServiceImpl1(logger);

换为

this.conn = new ConnServiceImpl2(logger);

使用抽象类:

using MyWebApiTest.Service;
using MyWebApiTest.Service.Imp;
using Serilog;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.


//日志
builder.Host.UseSerilog((context, logger) =>
{
    logger.ReadFrom.Configuration(context.Configuration);
    logger.Enrich.FromLogContext();
});

// Add services to the container.
builder.Configuration.AddJsonFile("appsettings.json", false, true);
var cfg = builder.Configuration;
builder.Services.AddSingleton<IConfiguration>(cfg);


builder.Services.AddSingleton<IConnFactoryService, ConnFactoryServiceImpl2>();
builder.Services.AddSingleton<IConnFactoryService, ConnFactoryServiceImpl1>();

builder.Services.AddControllers();
builder.Services.AddCors(c => c.AddPolicy("any", p => p.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()));
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseCors("any");

app.UseAuthorization();

app.MapControllers();

app.Run();


namespace MyWebApiTest.Service
{
    public abstract class AbstractConnService: IConnService
    {
        private bool conn;
        protected int i = 0;
        private ILogger<AbstractConnService> logger;

        public bool Conn { get; set; }
        public AbstractConnService(ILogger<AbstractConnService> logger)
        {
            this.logger = logger;
        }

        public virtual void ReadClass() 
        {
            i += 2;
            logger.LogInformation("虚方法在读取数据!@!");
            logger.LogInformation(i.ToString());
        }

        public abstract void ReadClass2();
    }
}

namespace MyWebApiTest.Service.Imp
{
    public class ConnServiceImpl2 : AbstractConnService
    {
        private ILogger<AbstractConnService> logger;

        public ConnServiceImpl2(ILogger<AbstractConnService> logger) : base(logger)
        {
            this.logger = logger;
        }

        public override void ReadClass2()
        {
            i += 5;
            logger.LogInformation("重写的抽象方法在读取数据!@!");
            logger.LogInformation(i.ToString());
        }
    }
}

namespace MyWebApiTest.Service.Imp
{
    public class ConnFactoryServiceImpl2 : IConnFactoryService
    {
        private readonly ILogger<AbstractConnService> logger;
        private AbstractConnService connService;

        public ConnFactoryServiceImpl2(ILogger<AbstractConnService> logger)
        {
            this.logger = logger;
            connService = new ConnServiceImpl2(logger);
        }
        public IConnService CreateConn()
        {
            connService.ReadClass();
            connService.ReadClass2();
            return connService;
        }
    }
}

using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
using MyWebApiTest.Service;
using MyWebApiTest.Service.Imp;

namespace MyWebApiTest.Controllers
{
    [Route("api/private/v1/[controller]/[action]")]
    [ApiController]
    [EnableCors("any")]
    public class MyTestController : ControllerBase
    {
        private readonly ILogger<MyTestController> logger;
        private readonly IEnumerable<IConnFactoryService> services;

        public MyTestController(ILogger<MyTestController> logger, IEnumerable<IConnFactoryService> services)
        {
            this.logger = logger;
            this.services = services;
        }

        [HttpGet]
        public void Test1()
        {
            IConnFactoryService? service1 = services.Where(s=>s.GetType() 
            == typeof(ConnFactoryServiceImpl1)).FirstOrDefault();

            service1?.CreateConn();

            IConnFactoryService? service2 = services.Where(s => s.GetType()
            == typeof(ConnFactoryServiceImpl2)).FirstOrDefault();

            service2?.CreateConn();

        }
    }
}

结果:

2023-08-14 23:57:02.744 +08:00 MyWebApiTest.Service.IConnService  [INF] ConnServiceImpl1在读取数据!!
2023-08-14 23:57:02.747 +08:00 MyWebApiTest.Service.IConnService  [INF] 1
2023-08-14 23:57:02.750 +08:00 MyWebApiTest.Service.AbstractConnService  [INF] 虚方法在读取数据!@!
2023-08-14 23:57:02.752 +08:00 MyWebApiTest.Service.AbstractConnService  [INF] 2
2023-08-14 23:57:02.754 +08:00 MyWebApiTest.Service.AbstractConnService  [INF] 重写的抽象方法在读取数据!@!
2023-08-14 23:57:02.757 +08:00 MyWebApiTest.Service.AbstractConnService  [INF] 7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

潘诺西亚的火山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值