- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有几个依赖类型为 ILogger
的类. ILogger
的执行需要知道它是记录器的类型,即 ILogger
对于 Foo
将是 new Logger(typeof(Foo))
, 对于 Bar
它将是new Logger(typeof(Bar))
等
我希望 Unity 自动注入(inject)适当的记录器;换句话说,当我调用 container.Resolve<Foo>()
, 我想要一个 new Logger(typeof(Foo))
注入(inject) Foo
实例。
如何在 Unity 中进行设置?有没有办法将正在解析的类型传递给依赖项?
(在我的真实代码中,我实际上有一个 ILoggerFactory
和一个 Create
方法,它也将类型作为参数。所以我可以将工厂传递给我的类,它们会调用 Create
自己获得合适的记录器,但它不像我想要实现的那样优雅)
一些让事情更清晰的代码:
interface ILogger
{
...
}
class Logger : ILogger
{
private readonly Type _type;
public Logger(Type type)
{
_type = type;
}
...
}
class Foo
{
private readonly ILogger _logger;
public Foo(ILogger logger) // here I want a Logger with its type set to Foo
{
_logger = logger;
}
}
这related question显示了我正在尝试做的事情,并且接受的答案正是我正在寻找的东西......但它适用于 NInject,而不是 Unity。
最佳答案
这是一个容器扩展,它将 Logger 构造函数的 Type 参数设置为 ILogger 注入(inject)的类型。
transient IBuilderContext.Policies 用于存储 ILogger 注入(inject)的类型。
也许它比需要的更复杂,但这似乎可行
public class LoggerExtension : UnityContainerExtension
{
public static NamedTypeBuildKey LoggerBuildKey = new NamedTypeBuildKey<Logger>();
protected override void Initialize()
{
Context.Strategies.Add(new LoggerTrackingPolicy(), UnityBuildStage.TypeMapping);
Context.Strategies.Add(new LoggerBuildUpStrategy(), UnityBuildStage.PreCreation);
}
}
public class LoggerTrackingPolicy : BuilderStrategy
{
public LoggerTrackingPolicy()
{
}
public override void PreBuildUp(IBuilderContext context)
{
if (context.BuildKey.Type != typeof(Logger))
{
var loggerPolicy = context.Policies.Get<ILoggerPolicy>(LoggerExtension.LoggerBuildKey);
if (loggerPolicy == null)
{
loggerPolicy = new LoggerPolicy();
context.Policies.Set<ILoggerPolicy>(loggerPolicy, LoggerExtension.LoggerBuildKey);
}
loggerPolicy.Push(context.BuildKey.Type);
}
}
}
public class LoggerBuildUpStrategy : BuilderStrategy
{
public LoggerBuildUpStrategy()
{
}
public override void PreBuildUp(IBuilderContext context)
{
if (context.BuildKey.Type == typeof(Logger))
{
var policy = context.Policies.Get<ILoggerPolicy>(LoggerExtension.LoggerBuildKey);
Type type = policy.Peek();
if (type != null)
{
context.AddResolverOverrides(new ParameterOverride("type", new InjectionParameter(typeof(Type), type)));
}
}
}
public override void PostBuildUp(IBuilderContext context)
{
if (context.BuildKey.Type != typeof(Logger))
{
var policy = context.Policies.Get<ILoggerPolicy>(LoggerExtension.LoggerBuildKey);
policy.Pop();
}
}
}
public interface ILoggerPolicy : IBuilderPolicy
{
void Push(Type type);
Type Pop();
Type Peek();
}
public class LoggerPolicy : ILoggerPolicy
{
private Stack<Type> types = new Stack<Type>();
public void Push(Type type)
{
types.Push(type);
}
public Type Peek()
{
if (types.Count > 0)
{
return types.Peek();
}
return null;
}
public Type Pop()
{
if (types.Count > 0)
{
return types.Pop();
}
return null;
}
}
它的工作原理是:当尝试解析不是 Logger 的类型时,在 TypeMapping 阶段(在任何创建之前),该类型被压入堆栈。稍后,在创建之前,如果类型是 Logger,那么它被注入(inject)的类型将从堆栈中窥视,并且该类型用作解析器覆盖。创建后,如果类型不是 Logger,则从堆栈中弹出。
还有一些代码来确保它正常工作(我向记录器添加了一个 Type 属性只是为了验证它是否设置正确):
class Program
{
static void Main(string[] args)
{
IUnityContainer container = new UnityContainer();
container.RegisterType<ILogger, Logger>();
container.AddNewExtension<LoggerExtension>();
var a = container.Resolve<A>();
var b = container.Resolve<B>();
var c = container.Resolve<C>();
var d = container.Resolve<D>();
var x = container.Resolve<X>();
}
}
public interface ILogger
{
Type Type { get; }
}
public class Logger : ILogger
{
private readonly Type _type;
public Logger(Type type)
{
_type = type;
}
public Type Type { get { return _type; } }
}
public class A
{
public A(ILogger logger)
{
System.Diagnostics.Debug.Assert(logger.Type == typeof(A));
}
}
public class B
{
public B(ILogger logger)
{
System.Diagnostics.Debug.Assert(logger.Type == typeof(B));
}
}
public class C
{
public C(A a, D d, B b, ILogger logger)
{
System.Diagnostics.Debug.Assert(logger.Type == typeof(C));
}
}
public class D
{
public D()
{
}
}
public class X
{
public X(Y y)
{
}
}
public class Y
{
public Y(ILogger logger)
{
System.Diagnostics.Debug.Assert(logger.Type == typeof(Y));
}
}
关于c# - 如何使用被解析的类型来解析依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35297344/
我一直在使用 AJAX 从我正在创建的网络服务中解析 JSON 数组时遇到问题。我的前端是一个简单的 ajax 和 jquery 组合,用于显示从我正在创建的网络服务返回的结果。 尽管知道我的数据库查
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我在尝试运行 Android 应用程序时遇到问题并收到以下错误 java.lang.NoClassDefFoundError: com.parse.Parse 当我尝试运行该应用时。 最佳答案 在这
有什么办法可以防止etree在解析HTML内容时解析HTML实体吗? html = etree.HTML('&') html.find('.//body').text 这给了我 '&' 但我想
我有一个有点疯狂的例子,但对于那些 JavaScript 函数作用域专家来说,它看起来是一个很好的练习: (function (global) { // our module number one
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 8 年前。 Improve th
我需要编写一个脚本来获取链接并解析链接页面的 HTML 以提取标题和其他一些数据,例如可能是简短的描述,就像您链接到 Facebook 上的内容一样。 当用户向站点添加链接时将调用它,因此在客户端启动
在 VS Code 中本地开发时,包解析为 C:/Users//AppData/Local/Microsoft/TypeScript/3.5/node_modules/@types//index而不是
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我在将 json 从 php 解析为 javascript 时遇到问题 这是我的示例代码: //function MethodAjax = function (wsFile, param) {
我被赋予了将一种语言“翻译”成另一种语言的工作。对于使用正则表达式的简单逐行方法来说,源代码过于灵活(复杂)。我在哪里可以了解更多关于词法分析和解析器的信息? 最佳答案 如果你想对这个主题产生“情绪化
您好,我在解析此文本时遇到问题 { { { {[system1];1;1;0.612509325}; {[system2];1;
我正在为 adobe after effects 在 extendscript 中编写一些代码,最终变成了 javascript。 我有一个数组,我想只搜索单词“assemble”并返回整个 jc3_
我有这段代码: $(document).ready(function() { // }); 问题:FB_RequireFeatures block 外部的代码先于其内部的代码执行。因此 who
背景: netcore项目中有些服务是在通过中间件来通信的,比如orleans组件。它里面服务和客户端会指定网关和端口,我们只需要开放客户端给外界,服务端关闭端口。相当于去掉host,这样省掉了些
1.首先贴上我试验成功的代码 复制代码 代码如下: protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
什么是 XML? XML 指可扩展标记语言(eXtensible Markup Language),标准通用标记语言的子集,是一种用于标记电子文件使其具有结构性的标记语言。 你可以通过本站学习 X
【PHP代码】 复制代码 代码如下: $stmt = mssql_init('P__Global_Test', $conn) or die("initialize sto
在SQL查询分析器执行以下代码就可以了。 复制代码代码如下: declare @t varchar(255),@c varchar(255) declare table_cursor curs
前言 最近练习了一些前端算法题,现在做个总结,以下题目都是个人写法,并不是标准答案,如有错误欢迎指出,有对某道题有新的想法的友友也可以在评论区发表想法,互相学习🤭 题目 题目一: 二维数组中的
我是一名优秀的程序员,十分优秀!