Unity 的自定义对象工厂扩展

2023-11-23

我正在使用 Unity IoC 容器,我需要拦截对某个基本接口的 Resolve 的任何调用,并运行我自己的自定义代码来构造这些类型。

换句话说,在下面的示例代码中,当我调用container.Resolve<IFooN>(),如果它没有具体实现类型的实例,它会调用MyFactoryFunction构造一个,否则我希望它返回缓存的副本。

标准 Unity 容器无法构造这些对象(update:因为它们是 .NET 远程处理对象,因此具体类不存在于本地计算机上的任何程序集中),并且我不想预先创建它们并使用 RegisterInstance 存储它们。

interface IFoo : IBase { ... }
interface IFoo2 : IBase { ... }

...
container.Resolve<IFoo2>();

...
IBase MyFactoryFunction(Type t)
{
    ...
}

我假设我可以创建一个 Unity 扩展来执行此操作,但我想知道是否已经有一个可以借用的解决方案。


为了完整起见,我应该添加另一个在 Unity 2 下工作的答案,因为我的另一个答案不再有效。由于您需要制定自定义构建器策略,因此涉及的内容稍微多一些。感谢 Unity 项目的 ctavares 提供了很多帮助这个线程在实施过程中:

public class FactoryUnityExtension : UnityContainerExtension
{
    private ICustomFactory factory;
    private CustomFactoryBuildStrategy strategy;

    public FactoryUnityExtension(ICustomFactory factory)
    {
        this.factory = factory;
    }

    protected override void Initialize()
    {
        this.strategy = new CustomFactoryBuildStrategy(factory, Context);
        Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
        Context.Policies.Set<ParentMarkerPolicy>(new ParentMarkerPolicy(Context.Lifetime), new NamedTypeBuildKey<ParentMarkerPolicy>());
    }
}

public class ParentMarkerPolicy : IBuilderPolicy
{
    private ILifetimeContainer lifetime;

    public ParentMarkerPolicy(ILifetimeContainer lifetime)
    {
        this.lifetime = lifetime;
    }

    public void AddToLifetime(object o)
    {
        lifetime.Add(o);
    }
}

public interface ICustomFactory
{
    object Create(Type t);
    bool CanCreate(Type t);
}

public class CustomFactoryBuildStrategy : BuilderStrategy
{
    private ExtensionContext baseContext;
    private ICustomFactory factory;


    public CustomFactoryBuildStrategy(ICustomFactory factory, ExtensionContext baseContext)
    {
        this.factory = factory;
        this.baseContext = baseContext;
    }

    public override void PreBuildUp(IBuilderContext context)
    {
        var key = (NamedTypeBuildKey)context.OriginalBuildKey;

        if (factory.CanCreate(key.Type) && context.Existing == null)
        {
            context.Existing = factory.Create(key.Type);
            var ltm = new ContainerControlledLifetimeManager();
            ltm.SetValue(context.Existing);

            // Find the container to add this to
            IPolicyList parentPolicies;
            var parentMarker = context.Policies.Get<ParentMarkerPolicy>(new NamedTypeBuildKey<ParentMarkerPolicy>(), out parentPolicies);

            // TODO: add error check - if policy is missing, extension is misconfigured

            // Add lifetime manager to container
            parentPolicies.Set<ILifetimePolicy>(ltm, new NamedTypeBuildKey(key.Type));
            // And add to LifetimeContainer so it gets disposed
            parentMarker.AddToLifetime(ltm);

            // Short circuit the rest of the chain, object's already created
            context.BuildComplete = true;
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity 的自定义对象工厂扩展 的相关文章

  • 必须打开存储才能执行此操作 - System.IO.Packaging.Package

    我正在使用 System IO Packaing Package 类来压缩文件 我的应用程序的多个实例可以同时运行 并读取和保存文件 当处理小文件时 一切似乎都很好 但是当涉及大文件时 如果应用程序的两个实例同时保存 我会收到一个异常 消息
  • 检查列表是否包含另一个列表。 C#

    编辑 只是说 ContainsAllItem 中的注释解释得最好 很抱歉问这个问题 我知道以前有人问过这个问题 但我只是不明白 好的 所以我想检查一个列表是否包含另一个列表中的所有项目WITHOUT重叠 以及根据类字符串 名称变量 称为项目
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何使用汇编获取BIOS时间?

    我正在从头开始实现一个小型操作系统 用于教育目的 现在 我想使用汇编来获取 BIOS 时间 我对此进行了很多搜索 但找不到任何代码示例来执行此操作 如果有人可以提供任何参考或代码示例或与此相关的任何内容 我将非常感激 See 时钟中断 1a
  • C# 中附加/分离事件处理程序的不同方式有什么区别

    我的问题有两个部分 首先 我们可以通过以下两种方式附加事件处理程序 myObject MyEvent new EventHandler MyHandler myObject MyEvent MyHandler 据我了解 这两者是等价的 在第
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • 将 C# 反射代码移植到 Metro-Ui

    我正在尝试移植使用反射的现有 C 类 通用工厂 但我无法编译这段代码 Type types Assembly GetAssembly typeof TProduct GetTypes foreach Type type in types i
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • 用 C# 制作 Vista 风格的应用程序

    我正在运行 Windows Vista 并且希望外观看起来像常规 Vista 程序 有没有关于如何构建 Vista 风格应用程序的真正好的教程 文章 我还想学习如何使用本机代码并将其转换为 C 如this http bartdesmet n
  • 如何使用泛型类型的 DataContractSerializer 编写自定义序列化器?

    我想编写一个自定义序列化器 用于将会话状态存储到Azure 缓存 预览版 这意味着这个自定义序列化器必须实现IDataCacheObjectSerializer 如果我错了 请告诉我 我需要编写这个自定义序列化程序的原因是我需要序列化一些包
  • 使用scanf()时如何区分整数和字符

    我只是使用该功能scanf 代码如下 scanf d a printf d a 当我输入1时 它会像我想要的那样打印1 但即使我输入 1a 它也会像以前一样打印 1 当用户输入非整数时 例如 2 3 12ab 1 a 我想向用户显示 输入整
  • QThread - 使用槽 quit() 退出线程

    我想在线程完成运行时通知对象 但是 我无法让线程正确退出 我有以下代码 处理器 cpp thread new QThread tw new ThreadWorker connect tw SIGNAL updateStatus QStrin
  • 更改其他页面的主窗口内容

    在 WPF 应用程序的主窗口中 我有一个 Badged 元素 来自材料设计 这是我的代码
  • 如何在 VS Code 中为 CMake 项目设置 C/C++ IntelliSense?

    我正在尝试使用 libTooling 编写一个工具 我对其进行了设置 以便它可以使用 LLVM 文档中的示例进行编译 然而 C C IntelliSense 似乎不适用于 CMake 项目 我的工具位于
  • asp.net c# 防止在从服务器端代码更改索引时触发 selectedindexchanged 事件

    我在同一个 aspx 页面上有两个下拉列表控件
  • 无法通过 LINQ to Entities 使用某些功能?

    我正在尝试使用 LINQ 查询在项目上实现搜索功能 由于数据有时包含带有重音符号和其他符号的字符 因此我创建了一种方法来删除这些字符以进行搜索 这是我的代码 var addresses from a in db Addresses join
  • 如何强制执行特定的 UserControl 设计

    我正在编写一个基本用户控件 它将由一堆其他用户控件继承 我需要对所有这些后代控件强制执行某种设计 例如 顶部必须有几个按钮以及一个或两个标签 后代用户控件区域的其余部分可以自由放置任何内容 最初 我认为我可以将一个面板放到 Base Use
  • 在何处将 CFLAG(例如 -std=gnu99)添加到 (Eclipse CDT) 自动工具项目中

    我有一个简单的 Autotools C 项目 不是 C 其框架是由 Eclipse CDT Juno 为我创建的 CFLAG 通过检查 似乎是 g O2 我希望所有生成的 make 文件也具有 std gnu99附加到 CFLAG 因为我使
  • 将文本从文本文件添加到 PDF 文件[重复]

    这个问题在这里已经有答案了 这是我的代码 using FileStream msReport new FileStream pdfPath FileMode Create step 1 using Document pdfDoc new D
  • 如何确定给定方法可以抛出哪些异常?

    我的问题和这个真的一样 找出 C 中方法可能抛出的异常 https stackoverflow com questions 264747 finding out what exceptions a method might throw in

随机推荐

  • 如何在运行时更改 Angular Material Datepicker 格式

    我正在研究一个Angular应用程序与Material设计 我正在使用Moment js解析和格式化日期 在我的其中一个页面中 我有一个材料的日期选择器 我遵循了材料的指南来使日期选择器与moment对象 而不是在本机上Date objec
  • 从自定义操作捕获 ArgumentTypeError 异常

    从我自己的自定义操作中抛出 ArgumentTypeError 异常并让 argparse 为我捕获它的最佳实践是什么 看来 argparse 的 try except 块不处理我的自定义操作的此异常 尽管它的内置操作做得很好 class
  • 如何从 checkout 获取 svn 版本号以在 dsl 中使用

    我创建了一个管道作业 并希望获取 svn 版本号 以便在调用 shell 脚本时启用进一步的下游处理 我正在使用类似于以下内容的管道脚本 node Mark the code checkout stage stage Checkout Ge
  • 在一个语句中打印多行,不带前导空格[重复]

    这个问题在这里已经有答案了 因此 对于我的第一个项目 它是一个简单的程序 可以打印您所在班级的姓名以及您就读的高中 让我困惑的一件事是对于其中的一个我必须使用一个print 所有这些的声明 我需要对其进行格式化 以便每条信息位于不同的行上
  • 尽管使用 DebugType=None,Visual Studio 发布仍生成 .pdb 文件

    我正在使用以下发布配置文件从 Visual Studio 中发布控制台应用程序
  • 如何使光标的高度与UITextField中文本的高度相同?

    我的 UITextField 光标太长 下图中 123123 的光标 如何让光标高度与文字高度一致 我偶然发现了这个问题 尽管它有点老了 但我还是觉得有必要回答它 因为接受的答案实际上是不正确的 您确实可以更改光标的高度 或宽度 只是子类化
  • 如何让java类线程安全?

    我有一个java类如下 class User String name String phone public String getName return name public String getPhone return phone 该类
  • 将 System.Drawing.Bitmap 转换为 stdole.StdPicture

    我当前有一个 System Drawing Bitmap 我需要将其转换为 stdole StdPicture 目前我正在使用 var pic stdole StdPicture Microsoft VisualBasic Compatib
  • 如何在 Mountain Lion 上安装 MySQLdb

    我是 Python 新手 在构建 MySQLdb 时遇到问题 试图让 Google AppEngine SDK 运行 我刚刚从 Snow Leopard 升级到 Mountain Lion 并安装了最新的 XCode 4 4 我已经下载了h
  • 无法使用 SelectListitem 获取不同的值

    我试图获取下拉列表的不同值 但是当使用以下语法时 它会带回所有行 有人可以告诉我如何使用正确的语法获取不同的值集吗 IEnumerable
  • Google 云端硬盘文档时间戳

    我假设修改日期搜索字段是修改日期 显然 或上传到驱动器的日期 有没有办法在其本机系统上保留文件的原始创建日期 或者有没有可能修改这个字段 谢谢你 肖恩 您可以使用 File Update 设置上传后的修改日期 https developer
  • Objective C - init 和构造函数之间的区别?

    我试图找到 Objective C 中 init 和构造函数之间的区别 我不是 C 开发人员 但我需要将一些 Objective C 代码转换为 Java 实际上我无法理解两者之间的区别 在 Objective C 中 对象的生成方式分为两
  • 在 Lambda 中捕获值而不是引用 [重复]

    这个问题在这里已经有答案了 我对 Eli Bendersky 给出的这个例子感到有点惊讶 http eli thegreenplace net 2015 the scope of index variables in pythons for
  • 我可以强制子类重写方法而不使其抽象吗?

    我有一个带有一些抽象方法的类 但我希望能够在设计器中编辑该类的子类 然而 设计者不能编辑子类 除非它可以创建父类的实例 所以我的计划是用存根替换抽象方法并将它们标记为虚拟 但如果我创建另一个子类 如果我忘记实现它们 我不会得到编译时错误 有
  • WooCommerce-如何从网址中删除产品和产品类别?

    我在 WordPress 上使用 WooCommerce 它将产品和产品类别添加到 URLs http dev unwaveringmedia com 8dim product category all party supplies htt
  • UnityMainThreadDispatcher 是做什么的?

    我读了这段代码 https github com johnjcsmith iPhoneMoCapUnity blob master Assets NetworkMeshAnimator cs 代码第62行周围有如下描述 这是在做什么处理 i
  • std::u32string 与 std::string 和 std::u16string 之间的转换

    我需要针对不同的 API 模块在 UTF 8 UTF 16 和 UTF 32 之间进行转换 因为我知道可以选择使用 C 11 所以我正在查看新的字符串类型 看起来我可以使用string u16string and u32string适用于
  • C# 从另一个窗口获取像素颜色

    我想从另一个窗口获取像素颜色 我的代码是 using System using System Drawing using System Runtime InteropServices sealed class Win32 DllImport
  • 在 iPhone 上合并两个 .caf 文件

    我一直在寻找答案 但似乎找不到 很多人问过 但没有人得到答案 我有一个使用 AVAudioRecorder 录制音频的应用程序 现在我只想将两个或多个录音合并到一个可以通过电子邮件发送的文件中 有谁知道如何做到这一点 这个答案建议使用称为音
  • Unity 的自定义对象工厂扩展

    我正在使用 Unity IoC 容器 我需要拦截对某个基本接口的 Resolve 的任何调用 并运行我自己的自定义代码来构造这些类型 换句话说 在下面的示例代码中 当我调用container Resolve