新框架PC后端代码(祈禧6月初版本)
南骏 池
3 天以前 72449a1b8699b65712e57fba8abce5a8240e9465
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
using System.Reflection;
using Gs.Toolbox.ApiCore.Common.Inject;
using Microsoft.AspNetCore.Builder;
 
namespace Gs.Toolbox.ApiCore.Extensions;
 
public static class ApplicationBuilderExtension
{
    public static void AddCustomInject(this WebApplicationBuilder builder)
    {
        builder.AddInterfaceInject();
    }
 
    private static List<AssemblyName> GetReferenceCustomAssembliesName(
        Assembly assembly)
    {
        var assembliesName = new List<AssemblyName>();
        assembliesName.Add(assembly.GetName());
        assembliesName.AddRange(assembly.GetReferencedAssemblies().ToList());
        return assembliesName;
    }
 
 
    public static void AddInterfaceInject(this WebApplicationBuilder builder)
    {
        builder.AddInterfaceInject(Assembly.GetEntryAssembly());
    }
 
    public static void AddInterfaceInject(this WebApplicationBuilder builder,
        Assembly assembly)
    {
        //最简单的实现就是实现了接口就注入
        AssemblyIsNullThrowException(assembly);
        var CustomAssembliesName = GetReferenceCustomAssembliesName(assembly);
        CustomAssembliesName.ForEach(a =>
        {
            var ass = Assembly.Load(a);
            var type = typeof(object);
            ass.GetTypes().ToList().ForEach(t =>
            {
                if (t.IsClass &&
                    InjectTypeChecker.IsImplementInjectType(t.GetInterfaces(),
                        out type)) InjectInContainer(builder, t, type);
            });
        });
    }
 
    private static void InjectInContainer(WebApplicationBuilder builder,
        Type ImplementType, Type injectType)
    {
        var attr = ImplementType.GetCustomAttribute<ExposeAttribute>();
        var firstInterface = ImplementType.GetInterfaces()[0];
        var services = builder.Services;
        //如果没有使用暴露属性,第一个接口为注入接口,直接注入实现注入接口类
        if (attr == null &&
            InjectTypeChecker.IsImplementInjectType(firstInterface))
            InjectTypeManager.Inject(services, null, ImplementType, injectType);
        //如果没有使用暴露属性,并且第一个接口不为注入接口,直接使用第一个接口作为对外接口
        if (attr == null &&
            !InjectTypeChecker.IsImplementInjectType(firstInterface))
            InjectTypeManager.Inject(services, firstInterface, ImplementType,
                injectType);
        //如果使用了暴露属性,直接注入属性里面的类型
        if (attr != null)
            // TODO 容错处理,比如说只实现了一个接口,且接口为注入接口怎么办?
            // 特性写了实现类型怎么办
            InjectTypeManager.Inject(services, attr.type, ImplementType,
                injectType);
    }
 
 
    private static void AssemblyIsNullThrowException(Assembly assembly)
    {
        if (assembly == null) throw new ArgumentNullException(nameof(assembly));
    }
}