I'm trying to figure out a standard way to dynamically register services with Optional Dependencies.
I have a method with dynamic registers rest services based on a configuration in your start up. (For Simplicity sake I will only put in things relevant to the question) I have a service Configuration which contains a builder to register validators:
public interface IServiceConfiguration<TEntity, TDTO>
{
IValidatorOptionsBuilder<TEntity> ValidatorOptions { get; set; }
}
The Builders internally have a way to register with the service collection
public interface IValidatorOptionsBuilder<TEntity>
{
void RegisterDynamicValidator(IServiceCollection serviceCollection);
}
I would like to provide 2 options of builders to use to my clients (with and with out optional dependencies) So I've additionaly created an interface to provide a single dependency to the client.
public interface IValidatorOptionsBuilder<TEntity, TDep> : IValidatorOptionsBuilder<TEntity>
{
}
To provide a full picture, the options builder can provide dependencies to the client like so:
public class ValidatorOptionBuilder<TEntity, TDep> : ValidatorOptionsBuilder<TEntity>,
IValidatorOptionsBuilder<TEntity,TDep>
{
private List<Action<DynamicContextualValidator<TEntity, TDep>>> _rules
= new List<Action<DynamicContextualValidator<TEntity, TDep>>>();
public ValidatorOptionBuilder<TEntity, TDep> AddRule(Action<DynamicContextualValidator<TEntity,TDep>> rule)
{
this._rules.Add(rule);
return this;
}
public virtual void RegisterDynamicValidator(IServiceCollection services)
{
services.AddScoped<IContextualValidator>(this.GetValidatorFactory);
services.AddScoped<IContextualValidator<TEntity>>(this.GetValidatorFactory);
}
private DynamicContextualValidator<TEntity, TDep> GetValidatorFactory(IServiceProvider serviceProvider)
{
var dependency = serviceProvider.GetRequiredService<TDep>();
var dynamicValidatorOptions = new DynamicValidatorOptions<TEntity, TDep>(dependency);
//TODO: this should be done in a more immutable way
dynamicValidatorOptions.Rules = this._rules;
return new DynamicContextualValidator<TEntity, TDep>(dynamicValidatorOptions);
}
}
This is complicating my registration because it requires the user to actively set the the options builder
s.ValidatorOptions = new ValidatorOptionsBuilder<User, UserAuthenticationManager>().AddRule(
(u) => {
u.AddRuleForEntityNotChanged(e => e.UniqueIdentifier).When(x => x.IsModified());
u.RuleForEntity(e => e.Id == u.Dependency.GetUserId())
.WithMessage("You do not have permission")
.When(x => x.HasChanges());
});
I could use a factory to provider the Options Builder, but I'm wondering if there's a simpler/standardized way to do what I'm attempting.
Aucun commentaire:
Enregistrer un commentaire