Архитектура для динамической регистрации сервиса с необязательными зависимостями - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь найти стандартизированный способ динамической регистрации служб с помощью необязательных зависимостей.

У меня есть метод с динамическими регистрами остальных служб, основанный на конфигурации при запуске. (Для простоты я приведу только то, что относится к вопросу) У меня есть Конфигурация службы, которая содержит компоновщик для регистрации валидаторов:

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());
        });
});

Я мог бы использовать фабрику для предоставления поставщика параметров, но мне интересно, есть ли более простой / стандартизированный способ сделать то, что я пытаюсь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...