Why Microsoft.P开发者_运维百科ractices.ServiceLocation.IServiceLocator
does not offer TryGetInstance()?
I need to get generic validator instance ServiceLocator.Current.GetInstance<IEntityValidator<TEntity>>()
but not all Entities has registered validator.
The only solution i found is to use try{}catch{} block, but i dont like this approach.
I can't tell you why this method doesn't exist, but I would like to offer the opion that it shouldn't matter because you shouldn't be using DI Containers in a pull-based way in any case. This is Service Locator anti-pattern.
If you need an IEntityValidator<Foo>
, then request the dependency through the constructor:
public class Foo
{
private readonly IEntityValidator<Foo> validator;
public Foo(IEntityValidator<Foo> validator)
{
this.validator = validator;
}
}
You can handle the issue that not all Entities have registered validators in different ways.
My preferred approach would be to register a Null Validator for all those entities.
Alternatively, you can give your Entities a constructor overload that doesn't take a validator, and then assign a Null Validator from that constructor. That might look like this:
public class Foo
{
private readonly IEntityValidator<Foo> validator;
public Foo()
{
this.validator = new NullValidator<Foo>();
}
public Foo(IEntityValidator<Foo> validator)
{
this.validator = validator;
}
}
However, whether that work or not partially depends on your particular DI Container. As an example, Castle Windsor uses the most greedy constructor it can satisfy so in that case it would work well even when validators are not registered, because it would just pick the default constructor.
In any case, the push-based approach is true Dependency Injection. With that approach, you use the DI Container to resolve the entire dependency graph in one go at the application's entry point.
The reason why this is not supported by the CSL is that not all IoC frameworks support this mechanism. The Common Service Locator discussion forum has a workaround for this issue. Read this question.
I agree with Mark that you should try registering a Null Object is you can and stick to true dependency injection when possible.
精彩评论