Dependency injection 具有类型定义构造函数的Setter注入

Dependency injection 具有类型定义构造函数的Setter注入,dependency-injection,types,structuremap,Dependency Injection,Types,Structuremap,我想知道这是否是我刚刚错过的非常简单的东西,或者是否还有更多 基本上,我要做的是将StructureMap的setter注入用于记录器实现。我希望StructureMap使用的记录器的构造函数接受用于创建记录器的类型参数: public class Logger : ILogger { private ILog _log = null; public Logger() { _log = LogManager.GetCurrentClassLogger(); } pub

我想知道这是否是我刚刚错过的非常简单的东西,或者是否还有更多

基本上,我要做的是将StructureMap的setter注入用于记录器实现。我希望StructureMap使用的记录器的构造函数接受用于创建记录器的
类型
参数:

public class Logger : ILogger
{
    private ILog _log = null;

    public Logger() { _log = LogManager.GetCurrentClassLogger(); }

    public Logger(string name) { _log = LogManager.GetLogger(name); }

    public Logger(Type loggerType) { _log = LogManager.GetLogger(loggerType); }

    // The rest of the implementation...
}
在我的引导代码中,我将其初始化为:

ObjectFactory.Configure(x => {
    x.FillAllPropertiesOfType<ILogger>().Use(l =>
        new Logger(l.BuildStack.Current.ConcreteType));
    // Further unrelated bootstrapping...
});
ObjectFactory.Configure(x=>{
x、 FillAllPropertiesOffType()。使用(l=>
新的记录器(l.BuildStack.Current.ConcreteType);
//进一步无关的引导。。。
});
这并不是100%起作用,可能只是我缺乏充分的理解。因此,关于我所看到的行为,我有几个问题:

  • 当我逐步通过调试器并深入到log4net实现时,记录器看到的“类型”是
    ILogger
    。如何使其成为包含正在注入的setter的类型
  • 仅设置StructureMap生成实例上的setter。例如,在数据访问层的存储库接口/实现上。其他对象,例如我的业务模型,不是从StructureMap图构建的,只是作为普通对象实例化。有没有一种方法可以告诉StructureMap也将注入到这些中?我想没有,因为它怎么知道?那么,如何为该类型解析正确构造的记录器实例呢?(我知道如何调用解析器,这是通过服务定位器实现的,但不知道如何调用它以满足此特定需求。)
  • 我突然意识到这“感觉不对劲”。也许我遗漏了一些关于命名实例的信息?因为如果引导程序成功地绘制了这个实现的图形,那么它将如何/何时为具有setter的每个类提供不同的实例

  • 也许有一种完全不同的/更简单的/更好的方式来完成我想做的事情,我欢迎大家的建议。基本上,我是在一个IoC容器后面抽象我的日志实现,我需要特定于类的记录器。

    也许这不是您想要的确切答案,但是为什么不通过创建一个
    iLogger工厂来简化一切呢?您可以注册
    ILogger工厂
    ,而不是注册
    ILogger工厂
    ,并将
    ILogger工厂
    注入到您的类中:

    public interface ILoggerFactory
    {
        ILogger CreateFor(string name);
        ILogger CreateFor<T>();
        ILogger CreateFor(Type loggerType);
    }
    
    public class LoggerFactory : ILoggerFactory
    {
        public ILogger CreateFor(string name)
        {
            return LogManager.GetLogger(name);
        }
    
        public ILogger CreateFor<T>()
        {
            return CreateFor(typeof(T));
        }
    
        public ILogger CreateFor(Type loggerType)
        {
            return LogManager.GetLogger(loggerType);
        }
    }
    
    公共接口工厂
    {
    ILogger CreateFor(字符串名称);
    ILogger CreateFor();
    ILogger CreateFor(loggerType类型);
    }
    公共类LoggerFactory:ILoggerFactory
    {
    公共ILogger CreateFor(字符串名称)
    {
    返回LogManager.GetLogger(名称);
    }
    公共ILogger CreateFor()
    {
    返回CreateFor(typeof(T));
    }
    公共ILogger CreateFor(类型loggerType)
    {
    返回LogManager.GetLogger(loggerType);
    }
    }
    
    很有趣。这可能就是出路。它看起来不像直接注入正确的记录器那样优雅,但它是可以使用的。不过,老实说,我也不觉得现有的实现完全优雅。关于类的内部记录器是可公开设置的,这一点我不太理解。(注意:这不是我的实现,我只是试着引导它。)我最终把它变成了相当优雅的东西,但核心原则与您建议的相同。我的IoC增强器现在连接了一个ILogger工厂和一个默认ILogger,前者可以用来抓取特定的非默认记录器。谢谢你的建议!顺便问一下,您真的需要使用特定类型的记录器实例吗?我知道这是log4net的一个特性,但我从来都不需要它。我经常看到开发人员在他们确实应该抛出异常的地方记录信息。在这几种情况下,您需要写入日志,您可以使消息更加详细,以便消息清楚地说明发生了什么(以防您还没有堆栈跟踪)。当您能够做到这一点时,只需再次注入ILogger并将其注册为单例。让生活更轻松。