IValidator
public interface IValidator
{
List<Error> Validate<T>(T request);
}
UserProfileValidator
public class UserProfileValidator : IValidator
{
public List<Error> Validate<T>(T request)
{
//Code for profile validation
}
}
UserLoginValidator
public class UserLoginValidator: IValidator
{
public List<Error> Validate<T>(T request)
{
//Code for login validation
}
}
UserService
private readonly IValidator _validator;
public UserService(IValidator validator)
{
_validator = validator;
}
public async Task<Response> Login(UserDetail userDetail)
{
//this is supposed to validate login details, but validates profile instead
var errors = _validator.Validate(userDetail);
}
public async Task<Response> UpdateProfile(Profile profile)
{
var errors = _validator.Validate(profile);
}
请指导。谢谢
答案 0 :(得分:2)
我正在发布此消息,尽管它可能无法解决OP的问题。
根据您所说的使用AutoFac。
服务:
builder.RegisterType<UserService>().As<IUserService>();
验证者:
builder.RegisterAssemblyTypes(typeof(DependencyBuilder).Assembly).Where(t => t.Name.EndsWith("Validator")).AsImplementedInterfaces().InstancePerLifetimeScope();
在查看如何注册UserService
时,您没有为其构造函数提供特定的IValidator
参数,我认为这是AutoFac继续使用UserProfileValidator
的原因。从逻辑上讲,UserService
将如何知道在运行时使用IValidator
的哪种实现?
我经常使用以下内容为构造函数指定参数。
builder
.Register(r => new UserService(r.Resolve<IValidator>()))
.As<IUserService>()
.InstancePerRequest();
但是问题在于,如果DI可以解决IValidator
,那么它仍然不是特定的。
我建议重新设计代码,因为我认为您当前的设计不允许UserService
同时使用UserProfileValidator
和UserLoginValidator
。
可能为每个视图模型分配IValidator
是一个更好的方法,这样每个视图模型都有自己的IValidator
实现,然后您可以执行类似var errors = viewModel.Validate();
的事情。
答案 1 :(得分:0)
您应该将界面更改为:
public interface IValidator<T>
{
List<Error> Validate(T request);
}
答案 2 :(得分:0)
您必须在默认的DI容器或Autofac中使用某些依赖项注入注册。请提供您的操作细节。
您的接口不是通用的,这意味着您的依赖项注入容器正在为同一接口注册多个实现,而在您注入它时,它将采用最后一个实现。
将界面更改为
public interface IValidator<T>
{
List<Error> Validate(T request);
}
并注入服务IValidator<UserDetail>
和另一个IValidator<Profile>
,因此从本质上讲,存在使用同一接口的不同验证器。
当实现是泛型时,可以使用泛型,但是在您的情况下,每个验证器都是不同的,因此DI需要确切知道要使用哪个验证器。
在autofac中,您应该有类似的东西
builder.RegisterType<UserLoginValidator>().As<IValidator<UserDetails>>();
builder.RegisterType<ProfileValidator>().As<IValidator<Profile>>();
答案 3 :(得分:0)
感谢大家的帮助,它确实帮助我解决了这个问题。我使用Autofac的键控服务将两个验证器都注册为IValidator,然后根据需要通过索引进行解析。
查看此: https://autofaccn.readthedocs.io/en/latest/advanced/keyed-services.html