【问题标题】:Get Instance from Simple Injector without "GetInstance" method不使用“GetInstance”方法从简单注入器获取实例
【发布时间】:2017-03-08 21:34:49
【问题描述】:

按照answer 我做了这个:

public class Log4netAdapter<T> : ILogger
{
    private static readonly log4net.ILog logger = LogManager.GetLogger(typeof(T));

    public void Log(LogEntry entry)
    {
        if(entry.LoggingEventType == LoggingEventType.Information)
            logger.Info(entry.Message, entry.Exception);
        else if(entry.LoggingEventType == LoggingEventType.Warning)
            logger.Warn(entry.Message, entry.Exception);
        else if(entry.LoggingEventType == LoggingEventType.Error)
            logger.Error(entry.Message, entry.Exception);
        else
            logger.Fatal(entry.Message, entry.Exception);
    }
}

然后是简单的注射器:

container.RegisterConditional(
    typeof(ILogger),
    c => typeof(Log4netAdapter<>).MakeGenericType(c.Consumer.ImplementationType),
    Lifestyle.Singleton,
    c => true);

如果我将 ILogger 注入到我需要的每个类构造函数中,这将非常有用。我的问题是我有一些类不能使用构造函数注入。对于这种情况,我通常会这样做:

var logger = SimpleInjectorInitializer.Container.GetInstance&lt;ILogger&gt;();

但是上述方法不起作用,它会在简单注入器类上引发错误,因为c.Consumernull

这里是我需要解析ILogger的例子之一,这个类是在webapi启动类上注册的。

public class ExceptionWebApiHandlingAttribute : IExceptionFilter
{
    public ExceptionWebApiHandlingAttribute()
    {
    }   
}

还有其他选择吗?

谢谢

【问题讨论】:

  • 您能否举例说明您需要在哪里解析ILogger 以及为什么这样做?
  • 嗨@Steven。非常感谢您的回复。我更新了我原来的问题。

标签: c# log4net simple-injector


【解决方案1】:

在应用程序边界上工作时,有时很难或不可能使用构造函数注入。典型示例是需要默认构造函数的 MVC 筛选器属性或 ASP.NET Web 表单Page 类。

解决这些问题的一个典型方法是将这样的边界类变成Humble Object,其中所有有趣的逻辑都从边界类中提取到一个组件中。边界类应该只包含对服务定位器的调用,并在解析的服务上调用一种方法。这最大限度地减少了应用程序中不可测试的代码量。

在所有其他情况下,应该首选构造函数注入。

但是,您解析 ILogger 的事实意味着您的边界类做得太多。相反,这个ILogger 应该是您从边界类中提取的组件的构造函数依赖项,以成为 Humble Object。

完成此操作后,您将不再直接解析ILogger,这解决了您的问题; ILogger 已成为消费者的依赖项,这确保 Simple Injector 能够代表您构建正确的 Logger&lt;T&gt;

在将依赖项应用于 Web API 中的异常过滤器(您的特定情况)时,一个好的解决方案是为您的异常过滤器创建一个代理,该代理会将调用委托给得到解析的真实过滤器。这可能是一些基础设施,并解释了这个概念here

如果无法应用上述建议,无论出于何种原因,您都可以直接从容器中请求Logger&lt;T&gt;

ILogger log = SimpleInjectorInitializer.Container.GetInstance<Logger<MyHumbleObject>>();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    • 2017-12-17
    相关资源
    最近更新 更多