【发布时间】: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<IService<FooRequest>>(() => new FooService()).InitializedBy((c, foo) => foo.Log = c.Resolve<ILog, Type>(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