gpt4 book ai didi

c# - 使用简单注入(inject)器解析通用装饰器

转载 作者:太空狗 更新时间:2023-10-30 00:30:31 26 4
gpt4 key购买 nike

我正在尝试构建一个结构,其中我有一个基础 IValidator<> 接口(interface),该接口(interface)将根据一些元数据为我们的系统生成。我们希望为 future 的开发人员提供灵 active ,以便 1) 如果需要,在不干扰任何手写代码的情况下重新生成 IValidator<> 的具体实现,以及 2) 向 IValidator<> 添加装饰器,以便能够在不干扰自动验证的情况下扩展功能生成的代码。

我希望有一些方法可以使用简单注入(inject)器的 RegisterDecorator 方法在运行时解析通用装饰器,这样我们的开发团队就不需要在每次添加装饰器时都去更新组合根。

这里有一些示例类/接口(interface)

public interface IValidator<T> where T : class
{
void Validate(T entity);
}
public class ClientValidator : IValidator<Client>
{
public void Validate(Client entity)
{
//Auto-generated
}
}
public class UserValidator : IValidator<User>
{
public void Validate(User entity)
{
//Auto-generated
}
}
public class ClientValidatorDecorator : IValidator<Client>
{
private readonly IValidator<Client> clientValidator;

public ClientValidatorDecorator(IValidator<Client> clientValidator)
{
this.clientValidator = clientValidator;
}
public void Validate(Client entity)
{
//New rules
this.clientValidator.Validate(entity);
}
}
public class UserValidatorDecorator : IValidator<User>
{
private readonly IValidator<User> userValidator;

public UserValidatorDecorator(IValidator<User> userValidator)
{
this.userValidator = userValidator;
}
public void Validate(User entity)
{
//New rules
this.userValidator.Validate(entity);
}
}
public class ValidationContext
{
private readonly IValidator<Client> client;
private readonly IValidator<User> user;

public ValidationContext(IValidator<Client> client, IValidator<User> user)
{
this.client = client;
this.user = user;
}
}

我们正在尝试做这样的事情:

public void RegisterServices(Container container)
{
container.Register(typeof(IValidator<>), AssemblyManifest.GetAssemblies());
container.RegisterDecorator(typeof(IValidator<>), GetType, Lifestyle.Transient, UseType);
}
private static Type GetType(DecoratorPredicateContext ctx)
{
//Return appropriate Decorator
}
private static bool UseType(DecoratorPredicateContext ctx)
{
//Predicate
}

不幸的是,除非我解析一个具体类型 RegisterDecorator 抛出一个错误,所以解析另一个泛型似乎是不可能的。我不确定如何进行。有没有办法做这样的事情?有没有更好的方法在没有装饰器的情况下获得预期的功能?我们在考虑部分类,但这有其自身的一系列问题。

任何帮助将不胜感激!

最佳答案

您可以使用复合验证器 来添加 IValidator<>,而不是插入装饰器。根据需要实现。此解决方案将允许代码包含多个 IValidator<>属于同一类型。

在内部,您的代码仍将能够依赖于单个 IValidator<T>这将解析为 CompositeValidator这将调用零个或多个验证器,具体取决于运行时在容器中注册的内容。

复合验证器:

public class CompositeValidator<T> : IValidator<T>
{
public readonly IEnumerable<IValidator<T>> validators;

public CompositeValidator(IEnumerable<IValidator<T>> validators)
{
this.validators = validators;
}

public void Validate(T item)
{
foreach(var validator in this.validators)
{
validator.Validate(item);
}
}
}

容器配置如下:

var assemblies = new[] { typeof(IValidator<>).Assembly };
var container = new Container();
container.RegisterCollection(typeof(IValidator<>), assemblies);
container.Register(typeof(IValidator<>), typeof(CompositeValidator<>));

哪里assemblies变量包含您要搜索验证器的所有程序集。

当您解析 IValidator<User> 时使用 container.GetInstance<IValidator<User>>()或者通过构造函数注入(inject),你可以返回 CompositeValidator<User>它在内部引用了所有 IValidator<User>的。

关于c# - 使用简单注入(inject)器解析通用装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35612320/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com