C# 如何避免Services.addScope对我的每个用例都适用?

C# 如何避免Services.addScope对我的每个用例都适用?,c#,dependency-injection,clean-architecture,asp.net-core-3.1,C#,Dependency Injection,Clean Architecture,Asp.net Core 3.1,我试图同时学习asp.net核心(3.1)和clean体系结构。我使用的GitHub存储库是最基本的,非常棒 所使用的方法非常好,回购所有人会回答您每种方法的原因。 我发现的问题不是现在的方法,而是更好的解决方案。 该类为其拥有的每个用例添加了一个范围: services.AddScoped<Application.Boundaries.CloseAccount.IUseCase, Application.UseCases.CloseAccount>();

我试图同时学习asp.net核心(3.1)和clean体系结构。我使用的GitHub存储库是最基本的,非常棒

所使用的方法非常好,回购所有人会回答您每种方法的原因。 我发现的问题不是现在的方法,而是更好的解决方案。 该类为其拥有的每个用例添加了一个范围:

        services.AddScoped<Application.Boundaries.CloseAccount.IUseCase, Application.UseCases.CloseAccount>();
        services.AddScoped<Application.Boundaries.Deposit.IUseCase, Application.UseCases.Deposit>();
        services.AddScoped<Application.Boundaries.GetAccountDetails.IUseCase, Application.UseCases.GetAccountDetails>();
        services.AddScoped<Application.Boundaries.GetCustomerDetails.IUseCase, Application.UseCases.GetCustomerDetails>();
        services.AddScoped<Application.Boundaries.Register.IUseCase, Application.UseCases.Register>();
        services.AddScoped<Application.Boundaries.Withdraw.IUseCase, Application.UseCases.Withdraw>();
        services.AddScoped<Application.Boundaries.Transfer.IUseCase, Application.UseCases.Transfer>();
services.addScope();
services.addScope();
services.addScope();
services.addScope();
services.addScope();
services.addScope();
services.addScope();

有没有办法让它通用?若要仅使用一行代码解析示例代码,并且在注入之后创建的所有用例?

显式注册依赖项可以被视为一种好处,因为您不会在运行时从看似“神奇”的注册中得到不必要的惊喜。这尤其正确,因为注册这些类型的约定似乎完全基于接口命名或名称空间。如果您想利用基于约定的注册,我建议您添加一些更强的标识符(例如,公共接口或标记接口)。否则,最好列出每一个DI注册,即使这看起来非常冗长

也就是说,有一些实用程序可以帮助您进行基于约定的注册。当然,您总是可以使用反射编写一些代码来自动注册这些内容。还有一个非常有用的实用程序包,它将根据约定为您注册类型

如果每个类型仅实现一个接口,则可以使用以下扫描将服务注册为其接口的作用域服务:

var type = typeof(Application.UseCases.CloseAccount);
services.Scan(scan => scan.FromAssembliesOf(type)
    .AddClasses(classes => classes.InExactNamespaceOf(type))
    .AsImplementedInterfaces()
    .WithScopedLifetime());

我的两分钱与反射我想你也许可以解决你的问题,有这样的功能在automapper它被称为扫描程序集。只要记住,“显式优于隐式”,如果你正在学习干净的代码,代码的可读性也很重要。如果(在这种情况下)您只有一个实现特定接口的具体类,那么您可以编写一个方法,接收接口并遍历应用程序中的所有类,以找到实现该接口的单个(或第一个)匹配类,并绑定它。但是你这样做真正得到了什么?干净的代码不是以牺牲可读性为代价节省几行代码!约定优先于配置可能是一个问题possibility@LeandroDeMelloFagundes既然有一个共同的基础,那么反射就可以用来查找所有派生接口及其实现。从这里开始,只需在服务集合中注册它们。谢谢@poke,我想这是最好的答案。在中,Mark Seemann和我的建议正好相反,我们说DI容器在与“显式注册”或“配置为代码”一起使用时基本上是无用的。在这种情况下,我们认为这更合适。DI容器在与“自动注册”和“约定优于配置”一起使用时开始变得有用。有关更多详细信息,请参见第节。