我上过简单的课程,有策略。
public class LinkQualifier : ILinkQualifier
{
private readonly IEnumerable<IQualifier> _qualifiers;
public LinkQualifier(IEnumerable<IQualifier> qualifiers)
{
_qualifiers = qualifiers;
}
public IQualifier Qualify(Uri uri)
{
return _qualifiers.FirstOrDefault(q => q.CanQualify(uri));
}
}
我如何在MVC核心DI容器中注册它?我发明了这样的东西:
services.AddTransient<ILinkQualifier, LinkQualifier>((ctx =>
{
var qualifiers = new List<IQualifier> {...};
return new LinkQualifier(qialifiers);
}));
但是那看起来很糟糕...有更好的解决方案吗?
答案 0 :(得分:2)
向ServiceCollection
注册多个实现。
IEnumerable<IQualifier>
依赖项将被DI容器识别并通过所有已注册的实现。
services.AddTransient<IQualifier, QualifierOne>();
services.AddTransient<IQualifier, QualifierTwo>();
services.AddTransient<IQualifier, QualifierThree>();
services.AddTransient<ILinkQualifier, LinkQualifier>();
需要明确的是,将按照实现的注册顺序添加实现。当注入调用代码时,它们将以相同的顺序返回。根据您的要求,这可能有用且重要。
引用ASP.NET Core Dependency Injection – Registering Multiple Implementations of an Interface
答案 1 :(得分:0)
我要假设您的IEnumerable<IQualifier>
可能来自生成/构造列表以外的其他内容。
在这种情况下,您可以创建一个接口和实现,以返回IEnumerable<IQualifier>
public interface IQualifiersProvider
{
IEnumerable<IQualifier> GetQualifiers();
}
public class QualifiersProvider : IQualifiersProvider
{
//from db / whatever
public IEnumerable<IQualifier> GetQualifiers()
{
return new [] {
new Qualifier(),
new Qualifier(),
}
}
}
更改您的LinkQualifier
以依赖于IQualifiersProvider
public class LinkQualifier : ILinkQualifier
{
private readonly IEnumerable<IQualifier> _qualifiers;
public LinkQualifier(IQualifiersProvider qualifiersProvider)
{
_qualifiers = qualifiersProvider.GetQualifiers();
}
public IQualifier Qualify(Uri uri)
{
return _qualifiers.FirstOrDefault(q => q.CanQualify(uri));
}
}
现在分别注册这些
services.AddTransient<IQualifiersProvider, QualifiersProvider>();
services.AddTransient<ILinkQualifier, LinkQualifier>();