【问题标题】:How can I resolve ILog using ServiceStack and Funq.Container如何使用 ServiceStack 和 Funq.Container 解决 ILog
【发布时间】:2023-03-24 19:14:01
【问题描述】:

ServiceStack AppHost 提供了一个 Funq.Container,用于注册可以在构造服务时注入到服务中的类型。这个容器可以用来注册一个 ILog 工厂,它返回一个适合它所在类型的 ILog 吗?

换一种说法,给定以下 AppHost:

public class AppHost : AppHostBase
{
    public AppHost() : base("Example Web Services", Assembly.GetExecutingAssembly())
    {
    }

    public override void Configure(Funq.Container container)
    {
        var baseLogFactory = new ServiceStack.Logging.NLogger.NLogFactory();
        LogManager.LogFactory = new ServiceStack.Logging.Elmah.ElmahLogFactory(baseLogFactory);
        // Would prefer to register a Func<Type, ILog> one time here
    }
}

还有一项服务:

public class FooService : IService<FooRequest>
{
    static ILog Log { get { return LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); } }
    // Would prefer:
    // public ILog { get; set; }

    public object Execute(FooRequest request)
    {
        Log.Info("Received request: " + request.Dump());
        return new FooResponse();
    }
}

有什么我可以添加到 AppHost.Configure 以避免在我的所有服务中使用静态 ILog 样板(而只使用普通的旧 ILog 属性)?

第三种方式,最简洁的说,我可以使用 Funq.Container 代替 LogManager 进行 ILog 注入吗?

【问题讨论】:

  • IIRC,Funq 不太适合自动属性注入。我想你可以实现任何类型的InitializedBy 部分并让它分配适当的记录器。所以container.Register&lt;IService&lt;FooRequest&gt;&gt;(() =&gt; new FooService()).InitializedBy((c, foo) =&gt; foo.Log = c.Resolve&lt;ILog, Type&gt;(typeof(FooService))) 但是你可以看到它是如何变得笨拙的,并且必须明确地将它应用于你打算登录的所有类型。就个人而言,我只是使用 sn-ps 插入您拥有的代码(但作为静态只读字段而不是避免额外查找的属性)
  • 另外,我并不热衷于将ILog 暴露为公共get/set 成员;当然,这对你来说是属性注入。我想这完全是另一场辩论。
  • IIRC, Funq isn't well suited for automated property injection - 恐怕你记错了。 ServiceStack 将为您完成。看我的回答。
  • @DarinDimitrov 啊,抱歉,我忽略了其中的“ServiceStack”部分。 :) 我之前的经验是直接使用 Funq,而不是使用 ServiceStack。太好了,你来这里是为了把我的脚从我嘴里拿出来!

标签: c# inversion-of-control servicestack funq


【解决方案1】:
container.Register<ILog>(
    ctx => LogManager.LogFactory.GetLogger(typeof(IService))
);

现在您的服务可能如下所示:

public class FooService : IService<FooRequest>
{
    public ILog { get; set; }

    public object Execute(FooRequest request)
    {
        Log.Info("Received request: " + request.Dump());
        return new FooResponse();
    }
}

【讨论】:

  • Funq 会自动解析/应用属性注入吗?我不认为它有(虽然记忆模糊)
  • 是的,它会自动进行构造函数属性注入。
  • 这很接近,但并不完全。我想获取具体类型的记录器,以便日志消息看起来像“2013-01-15 17:23:20.6192|INFO|FooService|...”而不是“2013-01-15 17:23: 20.6192|INFO|IService|..."
  • 我不确定这是否可行。
  • 注入 ILog 的目的是什么?除非你对 Nlog 中的 LogEventInfo 之类的东西做一些核心模块,否则我认为不需要注入它。这就是存在 LogManager 类的原因。要完成您所追求的,只需执行 ILog log = LogManager.GetCurrentClassLogger();
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多