问题
I`ve got simple class with strategies.
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));
}
}
How i can register it in MVC core DI container? I invented something like this:
services.AddTransient<ILinkQualifier, LinkQualifier>((ctx =>
{
var qualifiers = new List<IQualifier> {...};
return new LinkQualifier(qialifiers);
}));
But thats looks badly... is there a better solution?
回答1:
Register the multiple implementations with the ServiceCollection
.
The IEnumerable<IQualifier>
dependency will be recognized by the DI container and will pass all registered implementations.
services.AddTransient<IQualifier, QualifierOne>();
services.AddTransient<IQualifier, QualifierTwo>();
services.AddTransient<IQualifier, QualifierThree>();
services.AddTransient<ILinkQualifier, LinkQualifier>();
It’s worth making it clear that the implementations will be added in the order they are registered. They will be returned in that same order when injected into calling code. Depending on your requirements, this may be useful and important.
Reference ASP.NET Core Dependency Injection – Registering Multiple Implementations of an Interface
回答2:
I'm going to make an assumption your IEnumerable<IQualifier>
may come from something other than a generated / constructed list.
In which case, you could create an interface, and implementation, that returns the 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(),
}
}
}
Change your LinkQualifier
to take a dependency on 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));
}
}
Now register these separately
services.AddTransient<IQualifiersProvider, QualifiersProvider>();
services.AddTransient<ILinkQualifier, LinkQualifier>();
来源:https://stackoverflow.com/questions/53428178/register-collection-of-services-in-mvc-core-di