Web开发:ABP框架14——多个实现,一个接口的高端写法
一、方式一:环境变量决定实现
参考下面文章的 手动注入 ,不同环境变量的实现不一样,但是接口还是同一个。
其实这种方式下,若想切换实现,还是可以看方式二
Web开发:ABP框架8——仓储写法及其依赖注入的相关介绍_abp 中自动仓储需要安装哪些模块-CSDN博客
二、方式二:代码选择实现
【设计目标】
- 有接口IntefaceService,实现有两个:AService、BService
- 注入IntefaceService时,代码可选择实现谁
- 注入IntefaceService时,代码若未选择,默认实现是AService
【实现方式】
1.两个实现一个接口
分别写在三个.cs中,下面是方便展示才这样写:
public class AService : IntefaceService ,ITransientDependency //实现接口IntefaceService ,且生命周期设置为瞬态
{public AService(){}public string Product(string productId){return $"Product from Service A with ID {productId}";}
}public class BService : IntefaceService, ITransientDependency //实现接口IntefaceService ,且生命周期设置为瞬态
{public string Product(string productId){return $"Product from Service B with ID {productId}";}
}public interface IntefaceService
{public string Product(string productId);
}
2.高层服务接口
需要注入IntefaceService(抽象接口,有两个实现:AService、BService),注入IServiceProvider(框架自带,获取服务实现,类似于new一个类出来,即创建一个对象)
/// <summary>
/// 验证
/// </summary>
/// <returns></returns>
[Route("Check")]
[IgnoreAntiforgeryToken]
[HttpPost]
public async Task<string> Check(string db)
{var res = GetProductService(db).Product(Guid.NewGuid().ToString());var res2 = _intefaceService.Product(Guid.NewGuid().ToString());return res+"\n"+res2; //第一个参数由入参决定结果,第二个参数是默认实现的结果(我配置的默认实现是AService)
} //简单的创建型模式工厂(根据字符串返回实现)
private IntefaceService GetProductService(string serviceType)
{return serviceType switch{"A" => _serviceProvider.GetService<AService>(),"B" => _serviceProvider.GetService<BService>(),_ => throw new ArgumentException("Invalid service type")};
}
3.公共模块配置依赖注入
一个接口,多个实现,依赖注入,必须明确一个默认的实现,否则会报错!下面这句代码至关重要。
//BookStoreApplicationModule.cs
public override void ConfigureServices(ServiceConfigurationContext context)
{context.Services.AddTransient<IntefaceService, AService>(); // 如果有多个实现,必须选择一个默认的实现
}
【输出效果】
输入符合预期,上面这个随入参变化而变化,下面这个用的是依赖注入时的默认的实现