【发布时间】:2023-03-14 08:21:01
【问题描述】:
我目前正在开发一个 ASP.NET Core 项目,并希望使用内置的依赖注入 (DI) 功能。
嗯,我从一个界面开始:
ICar
{
string Drive();
}
并想多次实现ICar接口
public class BMW : ICar
{
public string Drive(){...};
}
public class Jaguar : ICar
{
public string Drive(){...};
}
并在Startup 类中添加以下内容
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();
services.AddTransient<ICar, BMW>();
// or
services.AddTransient<ICar, Jaguar>();
}
现在我必须在两个实现之间做出决定,我决定的类将设置在每个需要 ICar 实现的构造函数中。 但我的想法是,如果请求的 Controller 是 BMWController,则使用 BMW 实现,如果请求 JaguarController,则使用 Jaguar。
否则 DI 对我来说没有意义。我该如何正确处理这个问题?
为了更好地理解我的问题,看看这张照片:https://media-www-asp.azureedge.net/media/44907/dependency-injection-golf.png?raw=true 依赖解析器是如何工作的,我可以在 ASP.NET Core 的什么地方设置它?
在 Unity 中可以制作这样的东西
container.RegisterType<IPerson, Male>("Male");
container.RegisterType<IPerson, Female>("Female");
并像这样调用正确的类型
[Dependency("Male")]IPerson malePerson
【问题讨论】:
-
我认为这个想法是错误的。如果您有需要具体汽车实现的 BMWController,那么注入 ICar 没有任何意义——即 DI 的魔力——你说“给我 ICar 的实现”而不关心它是什么。我会准备一个单独的接口:
interface IBmwCar: ICar { ... }并将其注入BMWController。另一个想法是创建工厂。 f.eclass CarFactory : ICarFactory { ICar GimmeCar<TController>() }您已将控制器类型映射到具体实现。 -
如果我使用 IBmwCar 之类的东西,这不是接口溢出吗:我想要实现的所有品牌的 ICar?我只有 Drive 作为方法,不会有任何其他方法。好吧,我会创建 IBMW,IJaguar... 与 ICar 相同的签名,并为我实现的每个品牌使用这样的声明: services.AddTransient
();显然我可以使用工厂模式,但没有任何解决方案可以使用 DI 来完成我的工作吗? -
关于 DI 的一件事是您可以依赖 IEnumerable
并获取所有已注册的实现,如果没有注册任何实现,您将获得一个空列表而不是失败解决它。所以如果 ICar 有一些标识符属性,你可以在列表中找到你需要的那个。
标签: c# dependency-injection asp.net-core asp.net-core-mvc