configuration节点配置null、和自定义Attribute构造函数丢失踩坑

场景:framework里面注入了appsettings.json的配置(一个对象),会被使用框架的微服务中的appsettings.json覆盖,期望framework框架中的配置不需要配置此对象。

注入的配置对象:

namespace TestDemoProject
{
    public class Person2
    {
        public string Name { get; set; }
        public string Sex { get; set; }
    }
}

appsettings.json配置如下
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Person2": {

  }
}

如果不配置字段,他不会实例化这个Person2对象,这样会报错,如果期望默认的对象被实例化字段值都是默认值,达到builder.Services.AddSingleton(new Person2());同样的效果,只需要配置文件添加上至少一个字段即可
image-20240717222014553

修改配置之后

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Person2": {
    "Name": ""
  }
}

如图正常实例化此对象:

image-20240717222515316-1721227265640

也可以不配置,这样引入此框架的微服务,如果正确的配置了Person2,会覆盖此配置,没有则正常new 一个对象注入

builder.Services.AddSingleton(configuration.GetSection("Person2").Get<Person2>() ?? new Person2());

自定义Attribute踩坑:

出现的bug的场景, 一个net standard2.0的类库项目,写了一个自定义的attribute,举个例子:这样写是期望使用这个attribute的类,可传可不传这个参数。但实际上项目中,反射获取使用此attribute的时候,会报错,具体信息,不能截图,大概错误信息是System.MissingMethodException: ctor,,直接翻译就是构造函数缺失。

namespace TestDemoProject
{
    [AttributeUsage(AttributeTargets.Class)]
    public class FirstsaofanAttribute : Attribute
    {
        public string AuthorName { get; set; }

        public FirstsaofanAttribute(string authorName = null)
        {
            AuthorName = authorName;
        }
    }
}

使用FirstsaofanAttribute的类:

namespace TestDemoProject
{
    [Firstsaofan]
    public class Person
    {
        public const string Name = "John";
    }
}

使用场景代码:只是写的demo,代码无实际含义

项目中出现的错误的方法是Attribute.IsDefined(x,typeof(FirstsaofanAttribute),true),IsDefined这里抛出异常。

[HttpGet(Name = "TestCustomAttribute")]
public string TestCustomAttribute()
{
    //获取当前程序集中的所有类型
    var types = Assembly.GetExecutingAssembly().GetTypes().ToList().Where(x => Attribute.IsDefined(x,typeof(FirstsaofanAttribute),true));
    //实例化这个类型的class
    var s = types.First().GetConstructor([]).Invoke(new object[] { }) as Person;

    //获取这个类的属性
    var propertys = s.GetType().GetField("Name").GetValue(s);
    //获取这属性的值

    return propertys.ToString();
}

解决办法是:显式的保留默认的无参构造函数。

我事后自己写的demo,没有复现这个问题,第一次是net8 webapi项目,FirstsaofanAttribute写在此项目里面,第二次我也将此attribute新建一个net standard2.0的类库项目,放进去了,但是也没有此问题。

namespace TestDemoProject
{
    [AttributeUsage(AttributeTargets.Class)]
    public class FirstsaofanAttribute : Attribute
    {
        public string AuthorName { get; set; }

        public FirstsaofanAttribute()
        {
        }
        
        public FirstsaofanAttribute(string authorName = null)
        {
            AuthorName = authorName;
        }
    }
}

没什么技术含量,踩的坑,记录下,方便日后查阅而已。