首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用StructureMap处理行为变化?

如何使用StructureMap处理行为变化?
EN

Stack Overflow用户
提问于 2012-08-09 08:15:26
回答 1查看 130关注 0票数 0

我有一组注册到StructureMap的组件。根据实际租户的不同,解决组件的最佳方法是什么?

小示例:有两个租户,比如黄色和绿色。我有一个有两个实现的IValidatorYellowValidatorGreenValidator。假设应用程序是MVC,并且tentant来自URL。因此,我只需要根据租户的不同注入适当的IValidator

我见过许多多租户应用程序的解决方案,它们只处理数据的多租户,通常根据租户配置不同的数据库。这只涉及到参数传递。但这是在行为中发生变化的情况,而不是在数据中。我希望IoC容器能够透明地解析正确的实例。

编辑:更多信息: IValidator接口有一个简单的方法bool Validate(),但实现需要一些注入。

还有其他自定义验证器,但这两个租户都使用它们。

有一个明确的基于URL的临时策略。这意味着每个请求可以有一个不同的承租人,并且一个应用程序为两个承租人提供服务。

EN

回答 1

Stack Overflow用户

发布于 2012-08-16 03:28:00

给猫剥皮有很多方法。我很难猜出你的应用程序的设计,所以这里有一个想法。我想到的是将验证器隐藏在composite后面,让IValidator接口的用户对拥有许多实现一无所知。这样的组合可以看起来像这样:

代码语言:javascript
复制
public class ValidatorComposite : IValidator
{
    private IEnumerable<IValidator> validators;

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

    public bool Validate(object instance)
    {
        return this.validators.All(v => v.Validate(instance));
    }
}

您可以创建多个组合并按键注册它们,其中键是租户的名称(但没有键值注册可能也一样简单)。这些组合可以包装在另一个组合中,该组合将委托给适当的特定于租户的组合。这样的租户选择组合可能如下所示:

代码语言:javascript
复制
public class TenantValidatorComposite : IValidator
{
    private ITenantContext tenantContext;
    private IValidator defaultValidator;
    private IDictionary<string, IValidator> tenantValidators;

    public ValidatorComposite(
        ITenantContext tenantContext,
        IValidator defaultValidator,
        IDictionary<string, IValidator> tenantValidators)
    {
        this.tenantContext = tenantContext;
        this.defaultValidator = defaultValidator;
        this.tenantValidators = tenantValidators;
    }

    public bool Validate(object instance)
    {
        string name = this.tenantContext.CurrentTenant.Name;

        return this.defaultValidator.Validate(instance) &&
            this.tenantValidators[name].Validate(instance);
    }
}

ITenantContext是一个抽象,它允许您在当前上下文中获取当前租户。您可能已经有了类似的东西,但我设想了一个如下所示的实现:

代码语言:javascript
复制
class UrlBasedTenantContext : ITenantContext
{
    public Tenant Current
    {
        get
        {
            // Naive implementation.
            if (HttpContext.Current.Request.Url.Contains("tenant1"))
            {
                return Tenant1;
            }

            return Tenant2;
        }
    }
}

创建一个TenantValidatorComposite会很容易:

代码语言:javascript
复制
var defaultValidator = CompositeValidator(
    GetAllDefaultValidators());

var tenantValidators = new Dictionary<string, IValidator>()
{
    { "tenant1", new CompositeValidator(GetValidatorsFor("tenant1")) },
    { "tenant2", new CompositeValidator(GetValidatorsFor("tenant2")) },
};

var tenantValidator = new TenantValidatorComposite(
    new UrlBasedTenantContext(),
    defaultValidator,
    tenantValidators);

我希望这能帮到你。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11875060

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档