开发者

Setter Injection with Type-Defined Constructor

开发者 https://www.devze.com 2023-01-28 22:29 出处:网络
I wonder if this is something very simple that I\'m just missing, or if there\'s a lot more to this. Basically, what I\'m trying to do is use StructureMap\'s setter injection for a logger implementat

I wonder if this is something very simple that I'm just missing, or if there's a lot more to this.

Basically, what I'm trying to do is use StructureMap's setter injection for a logger implementation. The constructor for the logger that I wish for StructureMap to use accepts a Type parameter for creating the logger:

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...
}

In my bootstrapping code, I initialize it as thus:

ObjectFactory.Conf开发者_如何学Cigure(x => {
    x.FillAllPropertiesOfType<ILogger>().Use(l =>
        new Logger(l.BuildStack.Current.ConcreteType));
    // Further unrelated bootstrapping...
});

It's not quite working 100%, and it's probably just a lack of full understanding on my part. So I have a few questions regarding the behavior I'm seeing:

  1. The "type" that the logger is seeing, when I step through the debugger and drill down into the log4net implementation, is of ILogger. How can I get it to be of the type which contains the setter being injected?
  2. Only setters on StructureMap-built instances are being set. For example, on the repository interfaces/implementations for a data access layer. Other objects, such as my business models, aren't built from the StructureMap graph and are just instantiated as normal. Is there a way to tell StructureMap to also inject into those? I imagine there isn't, because how would it know? So then how can I resolve an instance of a properly constructed logger for the type? (I know how to call the resolver, which I do through a service locator, just not how to call it for this specific need.)
  3. It occurs to me that this "just doesn't feel right." Maybe I'm missing something about named instances? Because if the bootstrapper manages to graph an implementation of this, how/when then would it supply different instances for each class that has the setter?

Maybe there's an entirely different/simpler/better way to accomplish what I'm trying to do, and I welcome suggestions for that. Basically, I'm abstracting my logging implementation behind an IoC container, and I need class-specific loggers.


Perhaps this is not the exact answer you are looking for, but why not simplify everything by creating an ILoggerFactory? Instead of registering the ILogger, you can register a ILoggerFactory and inject the ILoggerFactory in your classes:

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);
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消