2014-02-12 67 views
4

說我有一個簡單的控制檯應用程序的依賴到主入口點:使用Autofac注入在一個控制檯應用程序

public static class Program 
{ 
    private static ILog Log { get; set; } 

    public static void Main() 
    { 
     Log.Write("Hello, world!"); 
    } 
} 

什麼是我可以使用Autofac注入日誌,確保讓最簡單的方法Log屬性在運行時不會爲空?問題是我不能通過Main()傳遞它,我試圖避免使用容器的服務位置(僅僅是因爲)。

回答

9

你應該做的是從你的主要提取所有的邏輯到一個類。這個類可以有一個依賴關係的構造函數。你在主體中解決這個類,然後調用它。這個類應該被認爲是整個應用程序。現在,Program課程中發生的所有事情都可以被認爲是您的Composition Root

// Begin composition root 
public static class Program 
{ 
    public static void Main(string[] args) 
    { 
     var container = ConfigureContainer(); 
     var application = container.Resolve<ApplicationLogic>(); 

     application.Run(args); // Pass runtime data to application here 
    } 

    private static IContainer ConfigureContainer() 
    { 
     var builder = new ContainerBuilder(); 

     builder.RegisterType<ApplicationLogic>.AsSelf(); 
     builder.RegisterType<Log>().As<ILog>(); 
     // Register all dependencies (and dependencies of those dependencies, etc) 

     return builder.Build(); 
    } 
} 
// End composition root 

public class ApplicationLogic 
{ 
    private readonly ILog log; 

    public ApplicationLogic(ILog log) { 
     this.log = log; 
    } 

    public void Run(string[] args) { 
     this.log.Write("Hello, world!"); 
    } 
} 

注意container.Resolve<ApplicationLogic>()只是解決ApplicationLogic類,它解決了整個對象圖包括ApplicationLogic的依賴關係的所有,以及依賴這些依賴關係的,等等。無論怎樣圖表很深。您唯一負責的是在ConfigureContainer()方法中註冊這些依賴關係。因此,有多於一個方法調用一個控制檯應用程序是有點不尋常的,如果有的話,它們應該總是在組合根中被調用或連線。

+1

對於那些不瞭解DI容器會組成整個對象的人,您可能需要進一步闡明圖形。它也可能有助於演示將主要參數傳遞給ApplicationLogic的用法。 – NightOwl888

+0

@ NightOwl888:隨意編輯我的問題。 – Steven

2

您必須配置一個容器某處。在控制檯應用程序中,Main()通常是那個地方。

+1

雖然Program是一個靜態類,但它可以在Program的靜態構造函數中完成:) –