//使用:services.AddDIServices();
/// <summary>
/// 标记服务
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
public class DIServicesAttribute : Attribute
{
/// <summary>
/// 生命周期
/// </summary>
public ServiceLifetime Lifetime { get; set; } = ServiceLifetime.Singleton;
/// <summary>
/// 指定服务类型
/// </summary>
public Type ServiceType { get; set; }
/// <summary>
/// 是否可以从第一个接口获取服务类型
/// </summary>
public bool InterfaceServiceType { get; set; } = true;
/// <summary>
/// 服务(实现)唯一标识
/// </summary>
public string Identifier { get; set; }
public DIServicesAttribute()
{
}
public DIServicesAttribute(Type serviceType) : this(serviceType, ServiceLifetime.Singleton, null, false)
{
}
public DIServicesAttribute(ServiceLifetime serviceLifetime) : this(null, serviceLifetime, null, true)
{
}
public DIServicesAttribute(string identifier) : this(null, ServiceLifetime.Singleton, identifier, true)
{
}
private DIServicesAttribute(Type serviceType, ServiceLifetime serviceLifetime, string identifier, bool interfaceServiceType)
{
ServiceType = serviceType;
Lifetime = serviceLifetime;
Identifier = identifier;
InterfaceServiceType = interfaceServiceType;
}
}
public static class DIServiceExtensions
{
/// <summary>
/// 注册应用程序域中所有有DIServices特性的类
/// </summary>
/// <param name="services"></param>
public static void AddDIServices(this IServiceCollection services)
{
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (var type in assembly.GetTypes())
{
foreach (var serviceAttribute in type.GetCustomAttributes<DIServicesAttribute>())
{
if (serviceAttribute != null)
{
var serviceType = serviceAttribute.ServiceType;
//类型检查,如果 type 不是 serviceType 的实现或子类或本身
//运行时 type 将无法解析为 serviceType 的实例
if (serviceType != null && !serviceType.IsAssignableFrom(type))
{
serviceType = null;
}
if (serviceType == null && serviceAttribute.InterfaceServiceType)
{
//serviceType = type.GetInterfaces().FirstOrDefault();
serviceType = type.GetInterfaces().LastOrDefault();
}
if (serviceType == null)
{
serviceType = type;
}
switch (serviceAttribute.Lifetime)
{
case ServiceLifetime.Singleton:
services.AddSingleton(serviceType, type);
break;
case ServiceLifetime.Scoped:
services.AddScoped(serviceType, type);
break;
case ServiceLifetime.Transient:
services.AddTransient(serviceType, type);
break;
default:
break;
}
}
}
}
}
}
}