C# Ninject注入属性构造函数、字段或方法

C# Ninject注入属性构造函数、字段或方法,c#,attributes,inversion-of-control,ninject,interceptor,C#,Attributes,Inversion Of Control,Ninject,Interceptor,我想知道以下是否可能,如果可能,如何做到这一点。 我会试着用下面的代码来解释它 public class RandomClass { ... //class is filled with stuff of none importance for this demonstration ... [LogScope("Start", "End")] //The important LogScope attribute! public virtual void

我想知道以下是否可能,如果可能,如何做到这一点。 我会试着用下面的代码来解释它

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.
}
这是我与
Ninject.extensions.Factory
绑定的
ILogScopeInterceptorFactory
接口 像这样:

Bind().ToFactory()

现在我要做的是仍然像这样使用
LogScopeAttribute
[日志范围(“开始”、“结束”)]
无需手动插入工厂,只需注入工厂,我如何才能做到这一点?

EDIT2:

我使用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拦截所有方法,它们需要是
公共的
虚拟的
。 我发现这对于日志记录非常方便,很容易缩进方法中记录的所有内容 如果我想要一个页眉和页脚,或者打印方法的执行时间,那么它就在那里。 这也可以嵌套

@FELIX

问题不是我不能得到内核。。。 如果我想通过调用内核来创建工厂,我可以这样做

public override IInterceptor CreateInterceptor(IProxyRequest request)
{
    var factory = request.Context.Kernel.Get<ILogScopeInterceptorFactory>();
    return factory.Create(_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>();
}
公共静态类容器
{
专用静态IKernel_容器;
静态容器()
{
_container=…;//创建内核并定义容器
}
公共静态IKernel当前{get{return}容器;}
}
公共LogScopeAttribute(字符串页眉、字符串页脚)
{
_页眉=页眉;
_页脚=页脚;
_logScopeInterceptorFactory=Container.Current.Get();
}

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

您无法在构造函数中访问内核,并且不能像我正在努力注入ILogScopeInterceptorFactory一样注入IResolutionRoot。但是这可以通过CreateInterceptor方法完成,就像通过IProxyRequest对象可以到达内核一样,但是这会破坏这个问题的全部目的。对不起。。。看起来当我研究这个问题的时候内核是静态的或者其他的。。。让我更新我的答案,我不认为这会有什么不同,然后做我已经在做的事情,问题是没有得到内核,我已经有了它。。。答案是不可能的,并解释为什么imo。当然,没有问题。。。我刚才看到的问题是“不必手动插入工厂,只需注入它,我如何才能做到?”。这是可能的-我举一个例子。。。所以你不能说这是不可能的。当然,可能有更好的答案!没问题:)我用答案编辑了我的问题,以便更好地用代码演示。
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>();
}