C# 默认依赖注入?
我需要在我的域中记录很多东西,因此我的大多数域和应用程序服务都依赖于日志实现。假设我创建了一个小合同:C# 默认依赖注入?,c#,dependency-injection,domain-driven-design,ninject,constructor-injection,C#,Dependency Injection,Domain Driven Design,Ninject,Constructor Injection,我需要在我的域中记录很多东西,因此我的大多数域和应用程序服务都依赖于日志实现。假设我创建了一个小合同: public interface ILogger { void Info(string message); } 太好了。现在,我实现了一个基于log4net的基础设施服务: public class Log4NetProxy : ILogger { private ILog _logger = LogManager.GetLogger(); public vo
public interface ILogger {
void Info(string message);
}
太好了。现在,我实现了一个基于log4net的基础设施服务:
public class Log4NetProxy : ILogger {
private ILog _logger = LogManager.GetLogger();
public void Info(string message) {
_logger.Info(message);
}
}
然而,由于我的大多数类都有其他依赖项,而不仅仅是一个记录器,所以我越来越接近注入模式上的构造函数
public class MyService : IMyService {
public MyService(ILogger logger, IRepository repo, IAlsoNeedSettings settings) {
}
}
如何避免注入设置或日志等基本核心需求,而只关注我真正需要的依赖关系?财产注入?服务面?静态日志工厂?[Rant+删除了关于拦截器的代码,因为这不是您需要的:)] 我发现属性注入通常是一种方法,因为它避免了通常不太有趣的样板代码 。。。我将构造函数值的第无数个等距赋值为 财产 我不知道如何在Autofac中使用它(我主要使用Castle.Windsor),但我推荐它作为一种低维护和避免构造函数膨胀的好方法 编辑:显然,Mark Seemann提到的问题提到拦截是处理这些案件的有效方法,因此我将收回我原来的rant+代码。我不确定它是否与他所指的相符,但它可能会给你一些想法
我真的很喜欢Castle Windsor拦截系统,它有点像面向方面的编程,您可以将解析的组件封装在拦截程序中,然后根据参数、方法名称等决定如何操作 下面是我的拦截记录器的一个示例:
public class LoggingInterceptor: IInterceptor
{
public void Intercept(IInvocation invocation)
{
using (Tracer t = new Tracer(string.Format("{0}.{1}", invocation.TargetType.Name, invocation.Method.Name)))
{
StringBuilder sb = new StringBuilder(100);
sb.AppendFormat("IN (", invocation.TargetType.Name, invocation.Method.Name);
sb.Append(string.Join(", ", invocation.Arguments.Select(a => a == null ? "null" : DumpObject(a)).ToArray()));
sb.Append(")");
t.Verbose(sb.ToString());
invocation.Proceed();
sb = new StringBuilder(100);
sb.AppendFormat("OUT {0}", invocation.ReturnValue != null ? DumpObject(invocation.ReturnValue) : "void");
t.Verbose(sb.ToString());
}
}
private string DumpObject(object argument)
{
// serialize object
}
}
然后在安装过程中注册此记录器侦听器,并将其应用于WCF服务中的感兴趣类:
// register interceptors
_container.Register(
Classes.FromAssemblyInThisApplication()
.BasedOn<IInterceptor>()
.WithServiceBase()
.Configure(c => c.Named(c.Implementation.Name))
);
// apply them
_container.Register
(
Component.For<IService>()
.ImplementedBy<ServicesImplementation.Service>()
.Named("Service")
.LifestylePerWcfOperation()
.Interceptors("LoggingInterceptor")
);
//注册拦截器
_集装箱。登记(
类。FromAssemblyInThisApplication()的
.BasedOn()
.WithServiceBase()
.Configure(c=>c.Named(c.Implementation.Name))
);
//应用它们
_集装箱。登记
(
用于()的组件
.由()实施
.已命名(“服务”)
.lifestyleperwcfooperation()
.拦截器(“记录拦截器”)
);
您可以考虑拦截需要IOGOGER的方法或具有IOGGER属性的类,并从拦截器中注入它。
查看面向方面编程<代码>私有ILOG-YLGGER = LogMealth.GETLogGER();<代码>是维修定位器,而不是喷油器。我使用Autofac,但是我仍然没有找到一种好的方法来注入不是为从头开始注入而设计的对象图(构造函数或属性/字段);通常有一些“根”需要集成,如果存在间隙,则可能需要公开容器以进行直接/SL解析(至少在图形可以重新开始解析自身之前)。相关:相关: