gpt4 book ai didi

c# - Ninject 注入(inject)属性构造函数、字段或方法

转载 作者:行者123 更新时间:2023-11-30 18:35:45 25 4
gpt4 key购买 nike

我想知道以下是否可行,如果可行,该怎么做。我会尝试用下面的代码解释它。

public class RandomClass
{
...
//class is filled with stuff of none importance for this demonstration
...

[LogScope("Start", "End")] //The important LogScope attribute!
public virtual void MyMethod()
{
...
//Doing something here but not the point now...
...
}

...
}

public LogScopeAttribute : InterceptAttribute
{
private readonly string _header;
private readonly string _footer;

public LogScopeAttribute(string header, string footer)
{
_header = header;
_footer = footer;
// This is just one of many constructors....
}

public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return request.Context.Kernel.Get<LogScopeInterceptor>(
new ConstructorArgument("header", _header),
new ConstructorArgument("footer", _footer));
// In the real version of this method there is more logic here for creating
// the right version of the interceptor, in regards to what constrcutor the
// LogScopeAttribute was called with.
}
}

public class LogScopeInterceptor : SimpleInterceptor
{
// No need to explain stuff here, (not of importance to the question)
// but what the interceptor does for me is write to log
// a header and footer and indent everything inside the logscope.
}

我想要的是注入(inject)一个ILogScopeInterceptorFactory进入LogScopeAttribute使用 Ninject,所以我不必在 CreateInterceptor 中调用内核方法,然后插入 ConstructorArgument对象我想这样做......

public LogScopeAttribute : InterceptAttribute
{
private readonly string _header;
private readonly string _footer;
private readonly ILogScopeInterceptorFactory _logScopeInterceptorFactory;

public LogScopeAttribute(ILogScopeInterceptorFactory logScopeInterceptorFactory ,string header, string footer)
{
_header = header;
_footer = footer;
_logScopeInterceptorFactory = logScopeInterceptorFactory;
}

public override IInterceptor CreateInterceptor(IProxyRequest request)
{
return _logScopeInterceptorFactory.Create(_header, _footer);
}
}

这是 ILogScopeInterceptorFactory我与 Ninject.extensions.Factory 绑定(bind)的界面像这样:

Bind<ILogScopeInterceptorFactory>().ToFactory();

public interface ILogScopeInterceptorFactory
{
LogScopeInterceptor Create(char separatorChar, string header, string footer);
LogScopeInterceptor Create(char separatorChar, string header);
LogScopeInterceptor Create(string header, string footer);
LogScopeInterceptor Create(string header);
LogScopeInterceptor Create(char separatorChar);
LogScopeInterceptor Create();
}

现在我想做的仍然是使用 LogScopeAttribute像这样 [LogScope("Start", "End")]无需手动插入工厂,只需注入(inject)它,我该怎么做?

编辑 2:

我正在使用 log4net 登录,我将在这里写下 LogScopeAttribute 的内容做,以及输出的样子。

[LogScope("The Start", "The End")]
public virtual void MyMethod()
{
logger.Info("Hello World!");
}

OUTPUT:
logger: The Start
logger: Hello World!
logger: The End

为了让 ninject 拦截所有方法,它们需要是 publicvirtual .我发现这对于日志记录非常方便,可以轻松缩进方法中记录的所有内容如果我想要一个页眉和页脚,或者打印方法的执行时间,它就在那里。这也可以嵌套...

@FELIX

问题不在于我无法获取内核...如果我想通过调用内核来创建工厂,我可以这样做。

public override IInterceptor CreateInterceptor(IProxyRequest request)
{
var factory = request.Context.Kernel.Get<ILogScopeInterceptorFactory>();
return factory.Create(_header, _footer);
}

如果我手动插入工厂,我将不得不为每个属性执行此操作

[LogScope(_logScopeInterceptorFactory, "header", "footer")]

那会很丑

最佳答案

因为你不能像在属性中那样做任何运行时......你将不得不作弊......

容器是全局的,所以我总是使用单例模式创建它...

public static class Container
{
private static IKernel _container;

static Container()
{
_container = ...; //Create the kernel and define container
}

public static IKernel Current { get { return _container; } }
}

public LogScopeAttribute(string header, string footer)
{
_header = header;
_footer = footer;
_logScopeInterceptorFactory = Container.Current.Get<ILogScopeInterceptorFactory>();
}

当然,通常使用 Container.Current.Get 是一种反模式。但是在某些情况下它是必需的(例如属性)。在理想的世界中,该属性会非常纤细 - ILogScopeInterceptorFactory 将完成所有工作(并且将是被测试的类)。

关于c# - Ninject 注入(inject)属性构造函数、字段或方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14579423/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com