.net core 使用MS DI提供多种服务
我想提供一个服务来做GetPhone() 像这样.net core 使用MS DI提供多种服务,.net-core,.net Core,我想提供一个服务来做GetPhone() 像这样 provider.GetService<People>().GetPhone(iphone4S).Use<IPhone>(phone => phone.Call("123456")); provider.GetService().GetPhone(iphone4S).Use(phone=>phone.Call(“123456”); 我试着在People()中做GetPhone()但是不行 如何做这项服务 我的服务
provider.GetService<People>().GetPhone(iphone4S).Use<IPhone>(phone => phone.Call("123456"));
provider.GetService().GetPhone(iphone4S).Use(phone=>phone.Call(“123456”);
我试着在People()中做GetPhone()但是不行
如何做这项服务
我的服务代码
public interface IPhone
{
string Call(string Num);
}
public class People
{
private IPhone _phone;
public People(IPhone phone) => this._phone = phone;
public void Use<TPhone>(Action<IPhone> config)
where TPhone : class, IPhone
{
config(this._phone);
}
public IPhone GetPhone()
{
return this._phone;
}
}
public class iphone4S : IPhone
{
....
}
public class iphone5S : IPhone
{
....
}
公共界面IPhone
{
字符串调用(string Num);
}
公营阶层人士
{
私人IPhone(u)电话;;
公众人士(IPhone手机)=>这个;
公共无效使用(操作配置)
其中TPhone:class,IPhone
{
配置(本手机);
}
公共IPhone GetPhone()
{
把这个还给我;
}
}
公共级iphone4S:IPhone
{
....
}
公共级iphone5S:IPhone
{
....
}
主程序:
ServiceProvider provider = new ServiceCollection()
.AddSingleton<People>()
.BuildServiceProvider();
Provider.GetService<People>().GetPhone(iphone4S).Use<IPhone>(phone => phone.Call("123456"));
ServiceProvider=newServiceCollection()
.AddSingleton()
.BuildServiceProvider();
Provider.GetService().GetPhone(iphone4S).Use(phone=>phone.Call(“123456”);
您需要能够使用同一界面(iphone4S
,iphone5S
)的多个实现(IPhone
)。Microsoft.Extensions.DependencyInjection没有对此方案的内置支持。然而,有许多解决这一限制的办法。在我看来,最好的方法之一是注册工厂,并根据输入参数创建所需的实例
要使用它,您不应该将IPhone
注入People
构造函数,而应该将factoryFunc
注入。然后在中使用
方法,在该方法中,您知道实现的类型(TPhone
),您可以使用以下方法创建一个实例:
public class People
{
private readonly Func<Type, IPhone> phoneFactory;
private IPhone _phone;
public People(Func<Type, IPhone> phoneFactory) => this.phoneFactory = phoneFactory;
public void Use<TPhone>(Action<IPhone> config) where TPhone : class, IPhone
{
_phone = phoneFactory(typeof(TPhone));
config(this._phone);
}
public IPhone GetPhone()
{
return this._phone;
}
}
如果在
Main()
method所在的同一程序集中定义了实现类,那么这将起作用。如果实现是在不同的程序集中定义的,您可以通过枚举所有加载的程序集来调整此方法,如本文所述。您想做什么?如果希望基于当前模型对服务使用不同的实现,只需在运行时检测模型并仅注册适当的服务即可。如果你想根据用户提供的数据找到一个对象,你要求的是数据检索,而不是依赖注入。电话型号在DI配置和呼叫之间不会改变。OP不必指定要使用的服务,只需注册相应的服务。然后,为什么OP在use
call中将TPhone
指定为参数?这是一个非常有趣的问题。我怀疑这是XY问题的一个例子。在运行时选择特定的实现是一个有效的方案。MarkSeemann在他的名著《.NET中的依赖注入》中用了整整一节来讨论这个问题(6.1.将运行时值映射到抽象)。我没说不是。注册10个变体是没有意义的,尽管只有一个可以使用,这是在启动时知道的
ServiceProvider provider = new ServiceCollection()
.AddSingleton<People>()
.AddTransient<iphone4S>()
.AddTransient<iphone5S>()
.AddTransient(factory => (Func<Type, IPhone>)(type => (IPhone)factory.GetService(type)))
.BuildServiceProvider();
provider.GetService<People>().Use<iphone5S>(phone => phone.Call("123456"));
var services = new ServiceCollection();
services.AddSingleton<People>()
.AddTransient(factory => (Func<Type, IPhone>)(type => (IPhone)factory.GetService(type)));
foreach (var iphoneType in Assembly.GetExecutingAssembly().GetTypes()
.Where(t => !t.IsAbstract)
.Where(t => typeof(IPhone).IsAssignableFrom(t)))
{
services.AddTransient(iphoneType);
}
var provider = services.BuildServiceProvider();
provider.GetService<People>().Use<iphone5S>(phone => phone.Call("123456"));