Using structuremap with log4net wrapper

时间秒杀一切 提交于 2019-11-28 18:02:33

If the type parameter is context-specific, I don't think this is going to work as shown. If you need to pass something context specific in the constructor, you are likely going to have to create a factory interface and implementation that returns an instance of the ILogger:

public interface ILoggerFactory
{
    ILogger Create(Type type);   
}

public class LoggerFactory : ILoggerFactory
{
    public ILogger Create(Type type)
    {
        return new Log4netLogger(type);
    }
}

It might be possible to bootstrap StructureMap to supply the instance you want based on the type, but that assumes a limited number of types that you know in advance.

We use a similar ILogger wrapper around log4net and typically use constructor injection. We use an interceptor as a factory method responsible for creating the Logger. Here is our typical registry for logging setup.

public class CommonsRegistry : Registry
{
    public CommonsRegistry()
    {
        For<ILogger>()
            .AlwaysUnique()
            .TheDefault.Is.ConstructedBy(s =>
            {
                if (s.ParentType == null)
                    return new Log4NetLogger(s.BuildStack.Current.ConcreteType);

                return new Log4NetLogger(s.ParentType);
            });

        var applicationPath = Path.GetDirectoryName(Assembly.GetAssembly(GetType()).Location);
        var configFile = new FileInfo(Path.Combine(applicationPath, "log4net.config"));
        XmlConfigurator.ConfigureAndWatch(configFile);
    }
}

The parent type null check is necessary when there are dependencies on concrete types.

The rest is optional log4net setup stuff.

One thing I do like about this setup is the ability to use a null loggers for unit testing.

I really need to get out of the habit of answering my own question, but for those who run across it, here's the answer.

return ObjectFactory.With(type).GetInstance<T>();

I actually have a wrapper to structuremap (to avoid exposing the structuremap dependency to my app) that looks like the following:

public static class ServiceManager
{
    public static T Get<T>()
    {
        return ObjectFactory.GetInstance<T>();
    }

    public static T Get<T>(Type type)
    {
        return ObjectFactory.With(type).GetInstance<T>();
    }
}

Any time in the code I need a logger, I call the following:

ServiceManager.Get<ILogger>(GetType()).Info("Logging page view...");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!