我有一个 ASP.NET 后端项目,其中包含几个小型类库项目作为参考。
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerComposeProjectPath>..\docker-compose.dcproj</DockerComposeProjectPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\src\Background\Publisher\Publisher.csproj" />
<ProjectReference Include="..\src\Common\Common.csproj" />
<ProjectReference Include="..\src\Data\Data.csproj" />
<ProjectReference Include="..\src\Identity\Identity.csproj" />
<ProjectReference Include="..\src\Transaction\Transaction.csproj" />
</ItemGroup>
</Project>
我打算在
ConfigureServices
方法中使用汇编来注册这些类库中定义的所有服务:
public static void ConfigureServices(this IServiceCollection services)
{
// TODO: Get all project references as an array to optimize below code.
var serviceTypes = Assembly.GetExecutingAssembly().GetTypes();
var idTypes = Assembly.Load("Identity").GetTypes();
var txTypes = Assembly.Load("Transaction").GetTypes();
serviceTypes = serviceTypes.Concat(idTypes).Concat(txTypes).ToArray()
.Where(t => typeof(IService).IsAssignableFrom(t)
&& !t.IsInterface && !t.IsAbstract)
.ToArray();
foreach (var serviceType in serviceTypes)
{
var interfaceType = serviceType.GetInterfaces()
.FirstOrDefault(i => typeof(IService).IsAssignableFrom(i));
if (interfaceType != null)
{
services.AddScoped(interfaceType, serviceType);
}
}
}
以下是我正在使用的一些示例服务。
// Common library
public interface IService
{
}
// Identity library
public interface IUserService : IService
{
}
public class UserService : IUserService
{
}
// Transaction library
public interface ITransactionService : IService
{
}
public class TransactionService : ITransactionService
{
}
是否可以在
ConfigureServices
的 Startup
方法中以数组形式检索所有引用的库项目?
您可以使用
Assembly.GetExecutingAssembly();
获取当前程序集,然后使用 IService 接口查询加载的程序集并将它们添加到作用域服务中。
更多详情,您可以参考下面的例子:
var currentAssembly = Assembly.GetExecutingAssembly();
var referencedAssemblies = currentAssembly.GetReferencedAssemblies()
.Select(Assembly.Load)
.ToList();
referencedAssemblies.Add(currentAssembly);
var serviceTypes = referencedAssemblies
.SelectMany(assembly => assembly.GetTypes())
.Where(type => typeof(IService).IsAssignableFrom(type) &&
!type.IsInterface &&
!type.IsAbstract)
.ToList();
foreach (var serviceType in serviceTypes)
{
var interfaceType = serviceType.GetInterfaces()
.FirstOrDefault(i => typeof(IService).IsAssignableFrom(i));
if (interfaceType != null)
{
builder.Services.AddScoped(interfaceType, serviceType);
}
}
结果: