Я пытаюсь найти стандартизированный способ динамической регистрации служб с помощью необязательных зависимостей.
У меня есть метод с динамическими регистрами остальных служб, основанный на конфигурации при запуске. (Для простоты я приведу только то, что относится к вопросу) У меня есть Конфигурация службы, которая содержит компоновщик для регистрации валидаторов:
public interface IServiceConfiguration<TEntity, TDTO>
{
IValidatorOptionsBuilder<TEntity> ValidatorOptions { get; set; }
}
У строителей есть возможность зарегистрироваться в коллекции услуг
public interface IValidatorOptionsBuilder<TEntity>
{
void RegisterDynamicValidator(IServiceCollection serviceCollection);
}
Я хотел бы предоставить 2 варианта компоновщиков для использования с моими клиентами (с необязательными зависимостями и без них), поэтому я дополнительно создал интерфейс для обеспечения единственной зависимости для клиента.
public interface IValidatorOptionsBuilder<TEntity, TDep> : IValidatorOptionsBuilder<TEntity>
{
}
Чтобы получить полную картину, компоновщик опций может предоставить клиенту зависимости следующим образом:
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);
}
}
Это усложняет мою регистрацию, поскольку требует от пользователя активной настройки компоновщика опций
При запуске я динамически регистрирую свои службы в соответствии с правилами, которые регистрируют фабрики для предоставления моих валидаторов в Коллекции услуг.
services.RegisterRestService<User, UserDTO>(s =>
{
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());
});
});
Я мог бы использовать фабрику для предоставления поставщика параметров, но мне интересно, есть ли более простой / стандартизированный способ сделать то, что я пытаюсь.