我想提供一个服务来做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
{
....
}
我在People()中尝试做GetPhone()但是没办法
如何做这项服务?
我的服务代码
ServiceProvider provider = new ServiceCollection()
.AddSingleton<People>()
.BuildServiceProvider();
Provider.GetService<People>().GetPhone(iphone4S).Use<IPhone>(phone => phone.Call("123456"));
主程序:
select * from annotations where imagename='00003.jpg' x <= 510 order by x desc limit 1;
答案 0 :(得分:1)
您需要能够使用同一接口(iphone4S
)的多个实现(iphone5S
,IPhone
)。 Microsoft.Extensions.DependencyInjection没有对此方案的内置支持。但是,这种限制有许多变通方法。我认为最好的之一(描述here)是根据输入参数注册工厂和创建所需实例。
要使用它,您应该注入IPhone
到People
构造函数,而不是工厂Func<Type, IPhone>
。然后在Use
方法中,您知道实现的类型(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()方法中,您应该只注册工厂和所有可能的实现:
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"));
<强>更新强>
如果你有IPhone
接口的很长的实现列表,你可以使用基于反射的方法注册它们:
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"));
如果在Main()
方法所在的同一程序集中定义实现类,这将起作用。如果在不同的程序集中定义了实现,则可以通过枚举所有已加载的程序集来调整此方法,如此answer中所述。