C# 如何保持(.NET Core)依赖项注入配置的可维护性?
我正在使用C# 如何保持(.NET Core)依赖项注入配置的可维护性?,c#,dependency-injection,.net-core,C#,Dependency Injection,.net Core,我正在使用Microsoft.Extensions.DependencyInjection进行依赖项注入在.netcore控制台应用程序中 public class Program { public IConfiguration Configuration { get; } public static void Main(string[] args) { IServiceCollection services =
Microsoft.Extensions.DependencyInjection
进行依赖项注入
在.netcore
控制台应用程序
中
public class Program
{
public IConfiguration Configuration { get; }
public static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
Startup startup = new Startup();
startup.ConfigureServices(services);
IServiceProvider serviceProvider = services.BuildServiceProvider();
var etlService = serviceProvider.GetService<IETLService>();
}
}
public class Startup
{
IConfigurationRoot Configuration { get; }
public Startup()
{
var builder = new ConfigurationBuilder()
.AddJsonFile("appsettings.json");
Configuration = builder.Build();
}
public void ConfigureServices(IServiceCollection services)
{
var sqlServerConnectionString = Configuration.GetConnectionString("SqlServerConnection");
services.AddDbContext<ETLSqlContext>(options =>
options.UseSqlServer(sqlServerConnectionString), ServiceLifetime.Scoped);
services.AddSingleton(Configuration);
services.AddTransient<ISqlRepository, SqlRepository>();
services.AddTransient<IAzureSqlRepository, AzureSqlRepository>();
services.AddTransient<IExtractService, ExtractService>();
services.AddTransient<ILoadService, LoadService>();
}
}
public class ExtractService : IExtractService
{
public ISqlRepository SqlRepository { get; set; }
public IAzureSqlRepository AzureSqlRepository { get; set; }
public ExtractService(ISqlRepository sqlRepository, IAzureSqlRepository azureSqlRepository)
{
SqlRepository = sqlRepository;
AzureSqlRepository = azureSqlRepository;
}
}
公共类程序
{
公共IConfiguration配置{get;}
公共静态void Main(字符串[]args)
{
IServiceCollection服务=新的ServiceCollection();
Startup Startup=新启动();
启动。配置服务(服务);
IServiceProvider serviceProvider=services.BuildServiceProvider();
var etlService=serviceProvider.GetService();
}
}
公营创业
{
IConfigurationRoot配置{get;}
公共启动()
{
var builder=new ConfigurationBuilder()
.AddJsonFile(“appsettings.json”);
Configuration=builder.Build();
}
public void配置服务(IServiceCollection服务)
{
var sqlServerConnectionString=Configuration.GetConnectionString(“SqlServerConnection”);
services.AddDbContext(选项=>
使用SQLServer(sqlServerConnectionString),ServiceLifetime.Scoped);
services.AddSingleton(配置);
services.AddTransient();
services.AddTransient();
services.AddTransient();
services.AddTransient();
}
}
公共类提取服务:IExtractService
{
公共ISqlRepository SqlRepository{get;set;}
公共IAzureSqlRepository AzureSqlRepository{get;set;}
公共提取服务(ISqlRepository-sqlRepository、IAzureSqlRepository-azureSqlRepository)
{
SqlRepository=SqlRepository;
AzureSqlRepository=AzureSqlRepository;
}
}
随着解决方案的发展,将会有更多的服务,例如50+服务,每个服务都需要在
启动.cs中注册其接口
和实现类
,以进行依赖项注入
。我需要知道有没有更好的方法来实现依赖注入
,它不需要在注册码中手动添加新的服务接口
和实现类
,我通过向每个项目“PluginConfiguration”添加一个类来实现这一点,该项目将在IServiceCollection中传递,并在构造函数中注册其单个服务。。然后在我的主项目中调用ServicesCollection中的每个“插件”。它将配置抽象为一个与单个项目相关的类,并使用每一个附加项目的一行代码保持主配置的整洁。在的第12章中,Mark Seemann和我描述了在使用DI容器时有多个配置选项,即:
- 配置文件–映射在配置文件中指定(通常为XML或JSON格式)
配置为代码
–代码明确确定映射
自动注册
–规则用于使用反射定位合适的组件并构建映射
您当前正在将配置作为代码应用。但是,使用自动注册
,您可以应用约定优于配置,以基于指定约定使用反射注册应用程序组件
在第12.3节中,我们详细描述了何时应该使用DI容器以及如何使用它。总之,我们声明:
通过使用自动注册
使用约定而不是配置,可以将上的维护量降至几乎为零
因此,我们建议:
Composition Root
应该关注于一些后期绑定类型,或者关注于自动注册
,可选地,作为code
和配置文件的少量配置。将配置作为代码来关注的组合根
是没有意义的,因此应该避免
在本书第6章和第10章中,我们还描述了您可以使用的设计类型,除此之外,最大限度地提高了对配置的约定,并使其最小化了DI配置的维护量。NET Core中的默认DI框架对您没有任何帮助,我建议使用Autofac之类的工具,让您可以进行更多的高级DI。您可以在
IServiceCollection
上编写一些扩展方法,以便将相关服务分组在一起。这将使你的startup.cs“更干净”。不过,我看不出有任何理由不以这种方式注册依赖关系。对于大型企业来说,组合根需要根据配置的条件约定实际组合一个抽象的不同实现,这会增加发现时间。