默认依赖注入



我需要在整个域中记录很多东西,因此我的大多数域和应用程序服务都依赖于记录实现。假设我创建了这个小合同:

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) {
    }
}

如何避免注入此类基本核心要求,例如设置或伐木,而只是专注于我真正需要的依赖项?财产注入?服务外墙?静态日志工厂?

[关于拦截器删除的关于拦截器的代码,因为那不是您需要的:)

我发现财产注入通常是要走的方式,因为它避免了通常并不有趣的样板代码

在 属性...

我不知道如何在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")
);

您可以考虑拦截需要iLogger或具有ilogger属性的类的方法并从拦截器注入它的方法。

最新更新