Unity / EntLib:将依赖项注入 CustomTraceListener

2024-03-10

抱歉,这是一个非常特殊的话题,所以很多人可能不感兴趣。 :-(

但是,我需要做以下事情:

  • 我有一个应用程序,它提供对某种控制台窗口的日志记录(它是一个 WPF 窗口,因为应用程序要求,而且应用程序即使在这里也需要看起来很华丽 - 我们的特殊客户要求这样做,并且每次我们见面时都会谈论它)

  • 为了提供与线程无关的日志记录,我创建了一个接口/实现对“IGUIController”/“GUIController”

到目前为止,一切都很好。一切都很好。

However:

  • 我需要我自己的自定义跟踪侦听器(我称之为“GUITraceListener”),它使用 IGUIController 接口将特定的日志消息写入那个华丽的 WPF 窗口

到目前为止,我的解决方案是在我的 GUIController 上有一个被黑的、旧的 skool 代码气味单例 - 样式“Current” - 属性(是的,我很羞愧,我确实知道这很糟糕),我像这样调用它:

GUIController.Current.Log(message);

显然,这是不行的。

因此,正确的方法是注入依赖项(当然)。然而,当我这样做时,我收到抱怨(运行时),我没有为我的 GUITraceListener 类提供带有 0(零)参数的构造函数。

事实上,我在这里明白了:

EnterpriseLibraryContainer.ConfigureContainer(configurator, 
ConfigurationSourceFactory.Create());

投诉是:

ArgumentException 未处理 无法为 GUITraceListener 找到合适的 0 参数构造函数

这实在是太糟糕了。我的意思是,Unity 是企业库的一部分,为什么那些人不简单地添加注入我的依赖项的可能性呢?

澄清:

我最终想要的是:

    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="guiController"></param>
    public GUITraceListener(IGUIController guiController)
    {
        // Store the dependencies
        this.m_GUIController = guiController;
    }

实体库5does有能力做到这一点。我猜你的监听器类上有一个 [ConfigurationElementType(typeof(CustomTraceListenerData)] ,对吗?

Entlib 5 被设计为独立于容器。因此,我们不能依赖任何类型的自动装配语义,因为每个容器的做法都不同。因此,您需要告诉 Entlib 要调用哪个构造函数,以及应该注入哪些依赖项。这是通过您的配置数据类完成的。

我举了一个简单的例子。这是跟踪侦听器 - 没什么特别的:

[ConfigurationElementType(typeof(GuiTraceListenerData))]
public class GuiTraceListener : TraceListener
{
    private readonly ILogFormatter formatter;
    private readonly IGuiController guiController;

    public GuiTraceListener()
        : this(string.Empty, null, null)
    {
    }

    public GuiTraceListener(string name)
        : this(name, null, null)
    {
    }

    public GuiTraceListener(string name, ILogFormatter formatter, IGuiController guiController) : base(name)
    {
        this.formatter = formatter;
        this.guiController = guiController;
    }

    public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id,
        object data)
    {
        if ((Filter == null) || Filter.ShouldTrace(eventCache, source, eventType, id, null, null, data, null))
        {
            if (data is LogEntry)
            {
                if (formatter != null)
                {
                    Write(formatter.Format(data as LogEntry));
                }
                else
                {
                    base.TraceData(eventCache, source, eventType, id, data);
                }
            }
            else
            {
                base.TraceData(eventCache, source, eventType, id, data);
            }
        }
    }

    public override void Write(string message)
    {
        guiController.Log(message);
    }

    public override void WriteLine(string message)
    {
        guiController.Log(message);
    }
}

有趣的部分在 GuiTraceListenerData 类中:

public class GuiTraceListenerData : TraceListenerData
{
    private const string formatterNameProperty = "formatter";

    public GuiTraceListenerData()
        : this("unnamed", null, TraceOptions.None)
    {
    }

    public GuiTraceListenerData(string name)
        : this(name, null, TraceOptions.None)
    {
    }

    public GuiTraceListenerData(string name, string formatterName)
        : this(name, formatterName, TraceOptions.None)
    {
    }

    protected GuiTraceListenerData(string name, string formatterName, TraceOptions traceOutputOptions)
        : base(name, typeof (GuiTraceListener), traceOutputOptions, SourceLevels.All)
    {
        ListenerDataType = typeof (GuiTraceListenerData);
        Formatter = formatterName;
    }

    [ConfigurationProperty(formatterNameProperty, IsRequired = false)]
    [Reference(typeof(NameTypeConfigurationElementCollection<FormatterData, CustomFormatterData>), typeof(FormatterData))]
    public string Formatter
    {
        get { return (string) base[formatterNameProperty]; }
        set { base[formatterNameProperty] = value; }
    }

    protected override Expression<Func<TraceListener>> GetCreationExpression()
    {
        return () =>
            new GuiTraceListener(Name,
                Container.ResolvedIfNotNull<ILogFormatter>(Formatter),
                Container.Resolved<IGuiController>());
    }
}

特别是查看 GetCreationExpression 方法。这告诉 entlib 要创建此配置 new 表示的对象,调用该构造函数,并解析格式化程序(如果指定了)和 IGuiController。

然后,在我的测试应用程序中(我使用 Winforms 只是为了快速)我初始化了我的容器和应用程序,如下所示:

static void Main()
{
    var container = new UnityContainer()
        .AddNewExtension<EnterpriseLibraryCoreExtension>()
        .RegisterType<IGuiController, MessageBoxGuiController>();

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(container.Resolve<Form1>());
}

我的 Form1 类采用 LogWriter 作为构造函数参数。

Entlib 5 构建方式的好处是,您在执行此操作时几乎可以获得自动配置工具支持 - 无需编写单独的配置节点。您的运行时配置元素就是您所需要的 - 只需将 DLL 复制到配置工具的同一目录中,它就会拾取它。

不管怎样,从这里开始就可以了。

希望这可以帮助。如果您想了解更多详细信息,请给我写信,我可以向您发送整个工作项目。

-Chris

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

Unity / EntLib:将依赖项注入 CustomTraceListener 的相关文章

  • 我应该封装我的 IoC 容器吗?

    想要改进这篇文章吗 提供此问题的详细答案 包括引用和解释为什么你的答案是正确的 不够详细的答案可能会被编辑或删除 我正在尝试确定花费额外的精力来封装 IoC 容器是否有意义 经验告诉我 我应该在我的应用程序和任何第三方组件之间放置一层封装
  • Unity 中的单例每次调用上下文(Web 请求)

    几天前 我遇到了 ASP Net 线程的问题 我希望每个网络请求都有一个单例对象 我实际上需要这个来完成我的工作单位 我想为每个 Web 请求实例化一个工作单元 以便身份映射在整个请求过程中都有效 这样我就可以使用 IoC 将我自己的 IU
  • 如何重置IOC容器中的所有实例

    我使用以下命令创建了一个 C WPF 应用程序MVVM轻框架 http www galasoft ch mvvm 我的应用程序使用ViewModelLocator类在运行时定位视图模型 这ViewModelLocator利用SimpleIo
  • 使用 PartCreationPolicy 导出 MEF 属性

    当我尝试这样做时 Export typeof IMyService PartCreationPolicy CreationPolicy Shared private MyService Service get var service new
  • 何时在 Ninject 中停用瞬态范围对象?

    当 Ninject 中的对象与InTransientScope 该对象不会放入缓存中 因为它是 呃 瞬态的并且没有任何范围 完成该对象后 我可以调用kernel Release obj 这会传递到缓存 在缓存中检索缓存的项目并调用Pipel
  • 如何编写库而不强迫用户使用库的 IOC 容器

    简短的问题是 给定一个图书馆warrants当应用程序使用该库时 在给定应用程序的情况下 将特定的 IOC 容器用于其内部warrants使用 IOC 容器来连接其依赖项 如果两个容器不同 它们如何才能很好地协同工作 场景是 应用程序定义了
  • 类型 IUserStore`1 没有可访问的构造函数

    我想使用 Unity 3 设置 MVC5 应用程序 我从标准模板创建了一个默认的 Web mvc5 应用程序 然后添加了 unity 当我访问 AccountController 中的注册操作时 出现以下异常 类型 IUserStore 1
  • Unity 与 ASP.NET Core 和 MVC6(核心)

    更新 09 08 2018Unity正在开发中here https github com unitycontainer container但我还没有时间测试它如何与 ASP NET Core 框架配合使用 更新 15 03 2018此解决方
  • C# Unity 错误:无法加载文件或程序集

    我在 Unity 上找到了这篇演示文章 看起来很简单 但我收到以下错误 无法加载文件或程序集 System Runtime CompilerServices Unsafe 版本 4 0 4 1 Culture neutral PublicK
  • Silverlight:如何处理标准程序集

    一个常见的 Silverlight 任务 减小 xap 文件的大小 有很多热门手册解释了如何使应用程序模块化 但我没有找到任何人解释如何制作 模块化 标准库 我的 xap 文件的最大部分 1 7Mb 当整体大小为 1 8Mb 时 被标准程序
  • 来自 Unity 配置文件的 RegisterType

    我正在从 Prism 4 迁移到 Prism 7 1 我似乎找不到已从最新 Prism 版本中删除的ConfigureContainer 方法 过去 我曾使用这种方法从文件系统加载Unity配置 对于最新版本的 Prism 库 这似乎是不可
  • EnterpriseLibrary.Logging 写入相差 1 小时的日志

    我们在日志记录方面遇到了一个奇怪的问题 我们正在使用Microsoft Practices EnterpriseLibrary Logging用于登录我们的 Web 应用程序的库 问题是它写入的日志与当前系统时间有 1 小时的差异 我们的记
  • 在 Unity 中的类型之间共享生命周期管理器?

    我在 Unity 文档中看到的示例让您通过输入来指定生命周期管理器new LifetimeManager 排队 所以我有这个代码 container RegisterType
  • 简单注入器从命名空间注册所有服务

    我的服务接口的命名空间为Services Interfaces 服务接口的实现有一个命名空间Web UI Services 例如 我有 2 个服务实现 IUserService 需要注册到UserService ICountryServic
  • Unity静态工厂扩展

    我似乎无法在任何地方找到 Microsoft Practices Unity StaticFactory dll 还有其他注册静态工厂的方法吗 寻找类似的东西 容器 RegisterFactory gt FooFactory CreateF
  • Unity(依赖注入):如何向RegisterType中的构造函数传入参数

    有人可以帮忙吗 我有一个 wpf 应用程序 应该没关系 在 Onstart 中我有我的 bootstrap 东西 就像这样 Create unity container my service and repository container
  • 企业库 CacheFactory.GetCacheManager 抛出空引用

    我正在尝试将使用 1 1 版本的企业库缓存块的应用程序转换为 2 0 版本 我认为我真正遇到的问题是不同 EntLib 部分的配置被分成几个文件 显然 这曾经是由ConfigurationManager 部分处理程序 但现在已经过时 取而代
  • 依赖注入和 ModelStateWrapper

    在教程中使用服务层进行验证 http www asp net learn mvc tutorial 38 cs aspx产品服务的构造函数如下所示 ProductService IValidationDictionary validatio
  • SimpleIoC - 在缓存中找不到类型:Windows.UI.Xaml.Controls.Frame

    第一次由 SimpleIoC 实例化我的 ViewModel 时 我遇到了以下错误 我相信我已经按应有的方式设置了容器 但由于某种原因 我仍然收到以下错误 任何想法或帮助将非常感激 Microsoft Practices ServiceLo
  • 我可以将 SimpleInjectors 诊断结果写入日志文件吗?

    在调用中使用简单注入器container Verify 在我的配置结束时 并在调试器中获取诊断信息 如中所述文档 http simpleinjector codeplex com wikipage title Diagnostics 我想将

随机推荐

  • 并非所有字节都读取常见解决方案

    在这篇文章中 我将详细介绍导致神秘错误消息的原因 Smart contract panicked panicked at Cannot deserialize the contract state Custom kind InvalidDa
  • 以编程方式修改 ActionBarDrawerToggle Drawable

    有谁知道在构造函数中通过资源 ID 设置用于 ActionBarDrawerToggle 的可绘制对象的方法吗 我正在使用导航抽屉 我想以编程方式将颜色过滤器应用于图标 但我不知道如何将其作为可绘制对象进行访问 任何帮助 将不胜感激 谢谢
  • 试运行中的 sed 命令

    如何进行空运行sed 我有这个命令 find type f xargs sed i s string1 string2 g 但在我真正替换所有文件之前 我想检查它会替换什么 复制整个目录结构来检查是不可能的 去除 i并将其通过管道传输到le
  • 通过 aws ses 发送带有 Node.js 附件的邮件

    有谁有一些如何发送带有附件的电子邮件的示例node js与 aws ses 一起吗 如果你想避免痛苦 你必须使用 Nodemailer 包装的 SES 直接使用AWS SDK 您无法使用以下方式发送附件ses sendEmail 你必须使用
  • 如何在不下载的情况下计算AWS S3中zip内的文件数量?

    案件 S3 存储桶中有一个很大的 zip 文件 其中包含大量图像 有没有一种方法无需下载整个文件即可读取元数据或知道 zip 文件中有多少个文件 当文件是本地文件时 在 python 中 我可以将其作为 zipfile 打开 然后调用 na
  • 如何强制编译器使用显式复制构造函数?

    我编写了一个小型测试程序 其中包含一个示例类 其中还包含自定义构造函数 析构函数 复制构造函数和赋值运算符 当我意识到复制构造函数根本没有被调用时 我感到很惊讶 即使我实现了带有我的类的返回值和像这样的行的函数Object o1 Objec
  • 为什么 openGL glDepthFunc() 不起作用?

    我正在玩 openGL 我试图摆脱蓝色标记的三角形 我用这个代码 glEnable GL DEPTH TEST glDepthFunc GL LESS glEnable GL CULL FACE 是的 我用 glClear GL COLOR
  • Matplotlib - 单值等高线图

    我想绘制一些数据的等值线图 但字段中的所有值可能都相同 这会导致 matplotlib 中出现错误 这是有道理的 因为实际上没有要创建的轮廓 例如 如果你运行下面的代码 你会得到一个错误 但删除第二个定义zi它按预期运行 如果某些数据是均匀
  • PowerShell 从远程 PC 删除桌面项目

    我有 200 台电脑需要删除一些特定的图标 我使用 ComputerName 创建了一个 CSV 文件 每行 1 个名称 我有另一个文件 其中包含需要从桌面删除的图标的文件名 Shortcut1 lnk 等 该其他文件也是 CSV 每行 1
  • 强制执行必须在*不同*字段中的每个子类中实现的属性的最佳方法是什么?

    我正在尝试想出 最好 的实施方式SQL 数据服务灵活的实体模型 http msdn microsoft com en us library cc512402 aspx其中每个类都可以存储为一个实体 甚至派生类 示例 每个子类都有不同的 st
  • 如何在不使用 for 循环的情况下对不同大小的矩阵的各个部分求和?

    我有一个相对较大的矩阵 NxN N 20 000 和一个 Nx1 向量 用于标识必须分组在一起的索引 我想将矩阵的各个部分相加 原则上可以有不同数量的元素和非相邻元素 我很快写了一个双 for 循环 它可以正常工作 但当然效率很低 探查器将
  • 使用 Python 从 Gmail 下载特定电子邮件

    有人可以帮我定制现有的代码示例吗 我可以从下面的文章中看到如何连接到gmail并下载内容 但我不知道如何搜索特定电子邮件并仅下载时间戳和正文 文章 如何从 Gmail 下载所有带附件的电子邮件 https stackoverflow com
  • 如何使用 C# 将 Excel 单元格设置为只读?

    Range range Range this workSheet Cells 1 1 range AllowEdit false 当我设置AllowEdit属性设置为 false 编译错误将显示 错误 属性或索引器 无法将 Microsof
  • Babel 转译地图可以在 IE11 中使用吗?

    查看Map文档 看起来IE11中并不完全支持 https developer mozilla org en US docs Web JavaScript Reference Global Objects Map https develope
  • setTimeout 不延迟 $.each 中的函数调用

    我的网站上有几个div 我想一一更新 为了不一次向服务器发送超过 200 个请求 我希望每个请求延迟 1 秒 我尝试过的 var tourBox tour box tourBox each function var box this set
  • InheritedWidget - 在 navigator.push 之后在 null 上调用 getter

    导航到新小部件后 我在尝试访问 InheritedWidget 时遇到问题 我有这样的顶级小部件 class App extends StatelessWidget build context return MaterialApp titl
  • 如何安装阴影罐子而不是原始罐子

    我将 maven shaded plugin 添加到我的项目中 它正确构建了着色的 uber jar 但仍然安装了原始的 Thin jar 我想安装阴影的超级罐子 以便下游项目可以依赖这个阴影的超级罐子 我该怎么做 谢谢 这是我的 pom
  • Matlab 中的非线性回归工具箱 (nlinfit)

    有谁知道MATLAB工具箱中非线性回归的算法和目标函数是什么 我正在查看 MATLAB 网站 但它没有提供信息 None
  • 如何在 ASP.NET 中通过 LAN 访问您的网站 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一个 asp net 网页应用程序 我希望使用局域网 LAN 或无线局域网 WLAN 访问它 我不知道从哪里开始 我需要配置什么才能让其他人访问我
  • Unity / EntLib:将依赖项注入 CustomTraceListener

    抱歉 这是一个非常特殊的话题 所以很多人可能不感兴趣 但是 我需要做以下事情 我有一个应用程序 它提供对某种控制台窗口的日志记录 它是一个 WPF 窗口 因为应用程序要求 而且应用程序即使在这里也需要看起来很华丽 我们的特殊客户要求这样做