3

我需要登錄很多東西都在我的領域,所以我的大部分領域和應用服務都依賴於日誌實現。假設我創建了這個小合同:默認依賴注入?

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

    } 

} 

如何避免像設置或日誌記錄這樣的基本核心需求的注入,只關注我真正需要的依賴關係?物業注入?服務外牆?靜態日誌工廠?

+0

看面向方面的編程 –

+0

'私人的ILog _logger = LogManager.GetLogger();'是一個服務定位器,而不是噴射器。我使用Autofac,但是我仍然沒有找到一種好方法來注入不是爲了注入而設計的對象圖(構造器或屬性/場);通常有一些需要整合的「根」,然後如果存在差距,它可能需要將容器暴露給直接/ SL解析(至少直到該圖可以開始再次解析)。 – user2864740

+0

相關:http://stackoverflow.com/q/2420193/126014 –

回答

1

[約,因爲刪除攔截咆哮+代碼不是你所需要的:)]

我發現財產注射,通常是去,因爲它避免了樣板代碼通常不是非常有趣的方式

...和我給你從構造值 屬性的無數ISomething ...

我不知道如何在Autofac使用它(我使用的主要是Castle.Windsor),但我會推薦它作爲一個低維護,避免臃腫的構造

編輯一個好辦法:很顯然,問題馬克塞曼指提攔截爲處理這些案件的有效方法,所以我會把我的背原始的rant +代碼。我不知道它匹配他指的是什麼,但它可能給你一些想法


我真的很喜歡城堡溫莎攔截系統,這是一個有點像面向方面的編程,並在那裏你包裝你解決組件攔截器,然後可以決定如何根據參數,方法名行事,等

這裏是我的攔截記錄的例子:

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屬性的類和自攔截將其注入調用。