具有不同构造函数参数的装饰器

2023-12-04

我想使用温莎城堡创建一个记录整数的类。但我想用其他类来装饰它几次。如果涉及的所有具体实体都具有可以解决的依赖关系,我可以看到这是如何工作的,但这里的情况并非如此。考虑这段代码:

public interface IRecorder
{
    void Add(int value);
}

public class NotifyingRecorder : IRecorder
{
    readonly IRecorder decoratedRecorder;

    public NotifyingRecorder(IRecorder decoratedRecorder)
    {
        this.decoratedRecorder = decoratedRecorder;
    }

    public void Add(int value)
    {
        decoratedRecorder.Add(value);
        System.Console.WriteLine("Added " + value);
    }
}

public class ModelUpdatingRecorder : IRecorder
{
    int seed;

    public ModelUpdatingRecorder(int seed)
    {
        this.seed = seed;
    }

    public void Add(int value)
    {
        seed += value;
    }
}

并注册:

container.Register(Component.For<IRecorder>().ImplementedBy<NotifyingRecorder>());
container.Register(Component.For<IRecorder>().ImplementedBy<ModelUpdatingRecorder>());

解决一个IRecorder永远不会在这里工作,因为ModelUpdatingRecorder具有非可选依赖性。我无法使用静态依赖项,因为seed在编译时是未知的。

有没有办法指定seed运行时参数并且装饰仍然有效吗?

此代码示例是我的场景的简化,但想法是相同的。我有装饰器,最低的装饰器依赖于提供给它的特定值/实例。


我找到了一个我认为应该这样做的解决方案。在温莎的内部DefaultDependencyResolver有一个方法用于解决子依赖关系(例如装饰实例IRecorder上面)称为RebuildContextForParameter。它调用它来创建一个新的上下文,以便在解析依赖项时使用(即构造函数的参数)。方法是:

/// <summary>This method rebuild the context for the parameter type. Naive implementation.</summary>
protected virtual CreationContext RebuildContextForParameter(CreationContext current, Type parameterType)
{
    if (parameterType.ContainsGenericParameters)
    {
        return current;
    }

    return new CreationContext(parameterType, current, false);
}

The false参数输入CreationContext构造函数是propagateInlineDependencies,当 true 时将复制current上下文的AdditionalArguments,从而将参数传递给子依赖项。

要翻转这个false to true,创建一个派生自的新类DefaultDependencyResolver:

public class DefaultDependencyResolverInheritContext : DefaultDependencyResolver
{
    protected override CreationContext RebuildContextForParameter(CreationContext current, Type parameterType)
    {
        if (parameterType.ContainsGenericParameters)
        {
            return current;
        }

        return new CreationContext(parameterType, current, true);
    }
}

然后在创建 Windsor 容器时使用它:

var kernel = new DefaultKernel(
                 new DefaultDependencyResolverInheritContext(), 
                 new NotSupportedProxyFactory());
var container = new WindsorContainer(kernel, new DefaultComponentInstaller());

The NotSupportedProxyFactory and DefaultComponentInstaller是使用无参数构造函数时的默认值DefaultKernel and WindsorContainer.

完成后,当使用工厂创建一个工厂时,上面的代码将起作用IRecorder, i.e.:

// during type registration/bootstrapping
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IRecorder>().ImplementedBy<NotifyingRecorder>());
container.Register(Component.For<IRecorder>().ImplementedBy<ModelUpdatingRecorder>());
container.Register(Component.For<IRecorderFactory>().AsFactory());

Where IRecorderFactory is:

public interface IRecorderFactory
{
    IRecorder Create(int seed);
}

然后这将按预期工作:

IRecorderFactory recorderFactory = container.Resolve<IRecorderFactory>();
IRecorder recorder = recorderFactory.Create(20);
recorder.Add(6);

希望这对其他人有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有不同构造函数参数的装饰器 的相关文章

随机推荐

  • 如何在 HTTP post 请求的消息正文中附加 XML 文件?

    如何在 HTTP post 请求的消息正文中附加 XML 文件 任何人都可以举出这样的例子吗 以下是对所需 URL 发出 HTTP POST 请求的示例代码片段 try String myXML
  • 不和谐.py |播放 url 中的音频

    我想让我的机器人从某个网址播放音频 但我不想下载该文件 这是我的代码 commands command name test async def test self ctx search morpheus tutorials discord
  • 覆盖包中的图像

    我有这个 ShopBundle Controller Resources public images marker png views Default index html twig 在我的index html twig中 我想要这个 im
  • 从数据集中获取 byte[] 并压缩

    我正在从 WCF 操作返回一个自定义类 使用的绑定是netTcp 该自定义类包含多个数据成员 其中之一是数据集 根据特定操作 数据集可能会很大 我计划将数据集压缩为字节 然后返回自定义类 根据阅读 我想出了以下代码来从数据集中返回压缩字节
  • 现实世界的 LR(k > 1) 语法?

    制作 k gt 1 的人工 LR k 语法很容易 Input A1 B x Input A2 B y introduce reduce reduce conflict for terminal a A1 a A2 a B b b b b t
  • Symfony2:即使存在对象,也调用非对象上的成员函数 getId() ?

    我不断收到此错误 em this gt getDoctrine gt getEntityManager movie em gt getRepository MyMyBundle Movie gt findMovieByName movien
  • 我想让面板具有粗边框。我可以以某种方式设置这个吗?

    我想让面板具有粗边框 我可以以某种方式设置这个吗 PS 我用的是C 对比 2008 年 Jim 我制作了一个用户控件 并给出了一个 ParentControlDesigner 正如我在评论中指出的那样 这并不是您所要求的完美解决方案 但这应
  • 按给定位置替换文件中的字符串

    我有一个以 ab 模式打开的文件 我需要做的是将文件中的一些字节替换为另一个字符串的字节 这样 FILE thisissomethingasperfectlygood string 01234 因此 例如 我寻找位置 4 0 并且我想在文件
  • ASP.Net 母版页和文件路径问题

    我正在尝试在我的母版页中添加对 jQuery 的脚本引用 以便它适用于任何页面 目前看起来像这样 问题是路径始终相对于执行的 aspx 页面 因此仅当 jquery js 文件位于同一文件夹中时才有效 为了使其工作 我必须将该行更改为 这显
  • 类名实例而不是数据 - Dart/Flutter

    我得到的是 DeviceClass 的实例 而不是实际的数据字段 这是我的数据模型 import package meta meta dart import dart convert Device deviceFromJson String
  • 在 NumPy 中使用频率数组检索数组元素

    我有一个数字数组 a 我有第二个数组 b 指定我想要检索相应元素的次数a 如何才能实现这一目标 在这种情况下 输出的顺序并不重要 import numpy as np a np arange 5 b np array 1 0 3 2 0 d
  • Android 谷歌地图 java.lang.NoClassDefFoundError: 解析失败: Lorg/apache/http/ProtocolVersion

    我正在使用 Google 地图 Android SDK 11 6 2 也尝试过 15 0 1 但在地图显示之前出现以下崩溃 已检查清单中的API密钥 它是可用的 但仍然出现此问题 我的 targetSDk 版本为 28 是否会导致此问题 j
  • 如何获取表或视图中的列列表?

    有时 我有兴趣获取 SQL Server 2008 R2 数据库中的一个表或视图中的列列表 例如 如果您在不使用昂贵的现成产品的情况下构建数据库文档 那么它很有用 获取此信息的简单方法是什么 另一种方法是查询 INFORMATION SCH
  • 在 Unity 中打电话?

    我在我的 C 脚本中使用了 Application OpenURL tel 79011111115 出现拨号器 但未拨打电话 如果是 Java 我可以说它的工作原理如下 Intent call new Intent Intent ACTIO
  • 如果对象返回为空字符串而不是空结构,如何解组 json 对象

    我收到一些 JSON 数据 但如果对象为空 它不会返回空结构 而是返回空 字符串代替 并且在解组时 它返回一个错误 所以而不是数据 key is key 即使使用 omitempty 字段也不起作用 例子 https play golang
  • 将数据从 PostgreSQL 传输到 MySQL

    您好 有什么方法可以将表布局和数据从 Postgres 数据库自动传输到 MySQL 吗 我必须将架构和数据迁移到 MYSQL 最简单的可能是使用 Postgres 将数据库 架构和数据 导出为 SQLpg dump效用 那么import将
  • 实体框架 4:多对多关系 IQueryable 而不是 ICollection

    大家 早安 我试图首先解决我在 EF 代码中遇到的问题 我的架构如下 public class Article IUrlNode Key public Guid ArticleID get set public string Title g
  • 为什么arguments.callee.caller.name未定义?

    为什么这不提醒 http 127 0 0 1 sendRequest 可在http jsfiddle net Gq8Wd 52 var foo sendRequest function alert bar getUrl var bar ge
  • docker: MISCONF Redis配置为保存RDB快照

    与此类似的问题还有很多 例如 Redis配置为保存RDB快照 但目前无法持久保存在磁盘上 Ubuntu Server MISCONF Redis 配置为保存 RDB 快照 但目前无法保留在磁盘上 可能修改数据集的命令被禁用 但这些都不能解决
  • 具有不同构造函数参数的装饰器

    我想使用温莎城堡创建一个记录整数的类 但我想用其他类来装饰它几次 如果涉及的所有具体实体都具有可以解决的依赖关系 我可以看到这是如何工作的 但这里的情况并非如此 考虑这段代码 public interface IRecorder void