具有可选依赖项的动态服务注册的体系结构

时间:2019-01-11 01:35:42

标签: c# design-patterns dependency-injection .net-core

我正在尝试找出一种标准化的方法,以使用可选依赖项动态注册服务。

我有一种方法,该方法基于启动时的配置来动态注册其余服务。 (为简单起见,我只输入与问题相关的内容)我有一个服务配置,其中包含用于注册验证程序的构建器:

doSomethingOnChange()

Builder内部有一种向服务集合进行注册的方法

public interface IServiceConfiguration<TEntity, TDTO>
{
    IValidatorOptionsBuilder<TEntity> ValidatorOptions { get; set; }
}

我想提供两个供我的客户端使用的构建器选项(带有和不带有可选依赖项),因此我另外创建了一个接口来为客户端提供单个依赖项。

public interface IValidatorOptionsBuilder<TEntity>
{
    void RegisterDynamicValidator(IServiceCollection serviceCollection);
}

要提供全貌,选项构建器可以像这样向客户端提供依赖项:

public interface IValidatorOptionsBuilder<TEntity, TDep> : IValidatorOptionsBuilder<TEntity>
{
}

这使我的注册复杂化,因为它要求用户积极设置选项生成器

在启动时,我会根据规则动态注册我的服务,这些规则会注册工厂以在Service Collection中提供我的验证器。

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

我可以使用工厂来提供“选项生成器”,但是我想知道是否有更简单/标准化的方法来执行我要尝试的操作。

0 个答案:

没有答案