【问题标题】:.Net Core + DI: Class To Centralize Interfaces.Net Core + DI:集中接口的类
【发布时间】:2021-08-13 03:55:46
【问题描述】:

我是 .Net Core 和 Microsoft 依赖注入的新手,我想做的是类似于 '.ToFactory()'(来自 ninject)的东西,我可以创建一个包含我所有接口服务的类,避免很多我的控制器上的 IMyClassService。 在 .Net Framework + Ninject 中我曾经这样做过:

NinjectModule

Bind< IAppServiceFactory >().ToFactory();

IAppServiceFactory 类

public interface IAppServiceFactory
{
    IAccessAgreementAppService AccessAgreement { get; }
    IAccessAgreementUserAppService AccessAgreementUser { get; }
    ...

控制器

private readonly IMapper _mapper;
private readonly IAppServiceFactory _appServiceFactory;

public MyController(IMapper mapper,
    IAppServiceFactory appServiceFactory)
{
    _mapper = mapper;
    _appServiceFactory = appServiceFactory;
}

public ActionResult Index()
{
    var all = _appServiceFactory.AccessAgreementUser.GetAll();
}

主要原因是有一个更干净的控制器,而不是

private readonly IAccessAgreementAppService _accessAgreementAppService;
private readonly IAccessAgreementUserAppService _accessAgreementUserAppService;
...
public MyController(IAccessAgreementAppService accessAgreementAppService,
    IAccessAgreementUserAppService accessAgreementUserAppService,
    ...

【问题讨论】:

  • 有点违背 DI 的目的。如果一个服务应该是 Scoped,而另一个应该是 Singleton 或 Transient。你强迫他们成为IAppServiceFactory 最终成为的样子。
  • 是的,我同意它,但同时我认为在我的控制器上拥有一堆服务也很糟糕,因为有时我有很多实体/接口我必须仅在一种方法/操作中进行交互并将所有业务逻辑放在控制器上,这对我来说听起来很糟糕“/
  • 那么如果你担心注入太多服务,你就将你的服务隔离得太多了。例如,您可以在您的示例中将它们组合成 IAccessAgreementService 的一部分。
  • 我想我不明白,例如:每次我插入 AccessAgreement 时,我都应该对 AccessAgreementUser 做一些事情,但是每个类都分隔在两个 diff 类中,所以我的上没有 2 次注入控制器,我怎样才能将这两个放在 IAccessAgreementService 中并让控制器免受业务逻辑的影响?
  • 对我来说,你正在做的事情对我来说就像是代码味道。在我看来,您的 MyController 使用了太多的依赖项,重组代码可能会解决这个问题。但是你的例子给出了一些细节来暗示这样做,这当然不是你的问题。 MS.DI 中没有 ToFactory 等效项。如果要保留该接口,则必须手动实现该IAppServiceFactory 并将其注册到IServiceCollection

标签: c# asp.net-core model-view-controller dependency-injection


【解决方案1】:

您可以申请IServiceProvider并自行获取服务。

 public MyController(IServiceProvider serviceProvider)
 {
         using (var scope = serviceProvider.CreateScope())
         {
             var service = scope.ServiceProvider.GetRequiredService<IAccessAgreementAppService();
             var all = service.GetAll();    
         }
 }

【讨论】:

  • 这是“确保依赖关系不再可见”的终极形式,基本上将 DI 的概念抛到了窗外。现在要知道MyController 依赖于什么,您必须打开构造函数,就像根本没有使用 DI 时一样。您还将代码绑定到特定的 DI 框架(尽管大多数人只使用过一个并且不会认为这是一个大问题)。如果它“只做一次”是可以原谅的,但是到处都这样做并传递根服务提供者以便您可以“灵活”的诱惑很大。
猜你喜欢
  • 2021-12-08
  • 2021-03-04
  • 2023-02-08
  • 2018-07-28
  • 2021-04-14
  • 2017-07-28
  • 1970-01-01
  • 2021-08-23
  • 1970-01-01
相关资源
最近更新 更多