一般注入比较麻烦,可以不依赖第三方组件命名空间注入
- using Microsoft.Extensions.DependencyInjection;
- using Newtonsoft.Json;
- using System.Reflection;
- using System.Reflection;
/// <summary>
/// 按照命名空间注册瞬时类
/// </summary>
/// <param name="services"></param>
/// <param name="namespaceName"></param>
/// <param name="assemblies"></param>
/// <returns></returns>
public static IServiceCollection AddTransientFromNamespace(
this IServiceCollection services,
string namespaceName,
params Assembly[] assemblies
)
{
foreach (Assembly assembly in assemblies)
{
IEnumerable<Type> types = assembly.GetTypes();
types = types.Where(t => t.IsClass);
Console.WriteLine(JsonConvert.SerializeObject(types));
types = types.Where(x => (x.Namespace??"").StartsWith(namespaceName, StringComparison.InvariantCultureIgnoreCase));
//types.Where(x =>
// x.IsClass
// && x.Namespace!.StartsWith(namespaceName, StringComparison.InvariantCultureIgnoreCase)
//);
foreach (Type? type in types)
{
if (services.All(x => x.ServiceType != type))
{
_ = services.AddTransient(type);
}
}
}
return services;
}
public static IServiceCollection AddSingletonFromNamespace(
this IServiceCollection services,
string namespaceName,
params Assembly[] assemblies
)
{
foreach (Assembly assembly in assemblies)
{
IEnumerable<Type> types = assembly
.GetTypes()
.Where(x =>
x.IsClass
&& x.Namespace!.StartsWith(namespaceName, StringComparison.InvariantCultureIgnoreCase)
);
foreach (Type? type in types)
{
if (services.All(x => x.ServiceType != type))
{
_ = services.AddSingleton(type);
}
}
}
return services;
}
/// <summary>
/// 按照命名空间注册作用域类
/// </summary>
/// <param name="services"></param>
/// <param name="namespaceName"></param>
/// <param name="assemblies"></param>
/// <returns></returns>
public static IServiceCollection AddScopedFromNamespace(
this IServiceCollection services,
string namespaceName,
params Assembly[] assemblies
)
{
foreach (Assembly assembly in assemblies)
{
IEnumerable<Type> types = assembly.GetTypes();
types = types.Where(t => t.IsClass);
Console.WriteLine(JsonConvert.SerializeObject(types));
types = types.Where(x => (x.Namespace ?? "").StartsWith(namespaceName, StringComparison.InvariantCultureIgnoreCase));
foreach (Type? type in types)
{
if (services.All(x => x.ServiceType != type))
{
_ = services.AddScoped(type);
}
}
}
return services;
}
/// <summary>
/// 移除指定服务
/// </summary>
/// <param name="services"></param>
public static void RemoveService<T>(this IServiceCollection services) where T : class
{
var serviceType = typeof(T);
// 查找服务的ServiceDescriptor
var descriptorToRemove = services.FirstOrDefault(d => d.ServiceType == serviceType);
// 如果找到了,从services中移除
if (descriptorToRemove != null)
{
services.Remove(descriptorToRemove);
}
}
/// <summary>
/// 替换指定服务
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="services"></param>
public static void Repalce<T,ReplaceType>(this IServiceCollection services,ServiceLifetime serviceLifetime)
where T : class where ReplaceType : class
{
var serviceType = typeof(T);
var serviceReplaceType = typeof(ReplaceType);
// 查找服务的ServiceDescriptor
var descriptorToRemove = services.FirstOrDefault(d => d.ServiceType == serviceType);
// 如果找到了,从services中替换
if (descriptorToRemove != null)
{
services.Replace(new ServiceDescriptor(serviceType, serviceReplaceType, serviceLifetime));
}
}
使用方法
class AppAssembly
{
public static Assembly ExecutingAsssembly => Assembly.GetExecutingAssembly();
}
private static readonly IHost appHost = Host.CreateDefaultBuilder()
.ConfigureAppConfiguration(c =>
{
c.SetBasePath(AppContext.BaseDirectory);
})
.ConfigureServices(
(_, services) =>
{
services.AddLogging(loggerBuilder =>
{
var nlog_configfile = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "NLog.config");
LogManager.Configuration = new XmlLoggingConfiguration(nlog_configfile);
NLog.ScopeContext.PushProperty("workername", "client");
loggerBuilder.ClearProviders();
loggerBuilder.AddNLog(LogManager.Configuration);
});
// 放类 IHostedService是后台服务类.NetCore功能
services.AddHostedService<HostedService >();
//放接口与实现类
services.AddSingleton<IDemo, Demo>();
//重点 ,命名空间注册...
services.AddTransientFromNamespace("Demo.AAAA",AppAssembly.ExecutingAsssembly);
//重点 ,命名空间指定dll...
var assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Demo.BBB.dll");
services.AddTransientFromNamespace("Demo.BBB", Assembly.LoadFrom(assemblyPath));
services.BuildServiceProvider();
}
) .Build();