2011-04-20 44 views
2

儘管我通常發現Autofac文檔(在wiki上)很有幫助,但關於XML配置和模塊的章節有點不清楚。現在,我有一個示例工作(我在下面介紹),但我不確定它是否代表了Autofac環境中的一種混合方法。特別是,我不確定在配置文件和代碼文件中是否真的需要我或多或少的東西。在autofac中使用模塊和配置文件

下面的代碼:

using System; 
using System.IO; 
using Autofac; 
using Autofac.Configuration; 

namespace AutofacTest.Animals 
{ 
    interface IAnimal 
    { 
     void Speak (); 
    } 

    abstract class Animal : IAnimal 
    { 
     protected TextWriter Writer 
     { 
      get; 
      private set; 
     } 

     protected Animal (TextWriter writer) 
     { 
      this.Writer = writer; 
     } 

     public abstract void Speak (); 

    } 

    class Dog : Animal 
    { 

     public Dog (TextWriter writer) 
      : base (writer) 
     { 

     } 

     public override void Speak () 
     { 
      this.Writer.WriteLine ("Arf!"); 
     } 
    } 

    class Cat : Animal 
    { 
     public Cat (TextWriter writer) 
      : base (writer) 
     { 

     } 

     public override void Speak () 
     { 
      this.Writer.WriteLine ("Meow"); 
     } 
    } 

    // In actual practice, this would be in a separate assembly, right? 
    class AnimalModule : Module 
    { 
     protected override void Load (ContainerBuilder builder) 
     { 
      builder.RegisterInstance (Console.Out).As<TextWriter> ().SingleInstance (); 
      builder.Register (d => new Dog (d.Resolve<TextWriter> ())).As<IAnimal> (); 
     } 
    } 

    class Program 
    { 
     static void Main () 
     { 
      Console.ForegroundColor = ConsoleColor.Yellow; 

      ContainerBuilder builder = new ContainerBuilder (); 
      ConfigurationSettingsReader reader = new ConfigurationSettingsReader(); 
      builder.RegisterModule (reader); 
      //builder.RegisterModule (new AnimalModule ()); 
      builder.Build ().Resolve<IAnimal> ().Speak (); 
      Console.ReadKey (); 
     } 
    } 
} 

這裏還有一個相關的配置文件:

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <configSections> 
     <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration"/> 
    </configSections> 
    <autofac defaultAssembly="AutofacTest"> 
     <components> 
      <component 
       type="AutofacTest.Animals.Cat" 
       service="AutofacTest.Animals.IAnimal" /> 
      <component type="System.IO.StreamWriter" service="System.IO.TextWriter"> 
       <parameters> 
        <parameter name="path" value="C:\AutofacTest.txt"/> 
        <parameter name="append" value="false" /> 
       </parameters> 
       <properties> 
        <property name="AutoFlush" value="true" /> 
       </properties> 
      </component> 
     </components> 
     <modules> 
      <module type="AutofacTest.Animals.AnimalModule, AutofacTest"/> 
     </modules> 
    </autofac> 
</configuration> 

這一切工作正常。應用程序將「Meow」輸出到文本文件。如果我註釋掉組件元素,應用程序會輸出「Arf!」到控制檯。

那麼,一切都好嗎?還是有更好的方法來解決這個問題?

而且我有點不確定背後基於模塊的配置思路:

我是正確的是,在實際操作中,模塊應該是在單獨的組件從應用程序的其他部分?

我是否正確理解模塊的主要功能之一是爲DI容器提供一組默認配置設置?

理想情況下,我的配置文件應該有多廣泛?換句話說,使用Autofac時,我需要了解哪些配置文件反模式?

謝謝(我認爲)提前爲您的答覆。

musicologyman

+1

只是一個提醒,可節省其他人的時間和精力 - 在AutoFac 4.0,這是*不再*有效。有關如何使用配置,請參閱版本4.0的文檔。 – codeputer 2016-09-07 23:03:29

回答

4

我個人的建議是少用XML配置。我只會將它用於您需要重新編譯而無需重新編譯的部分。例如,如果你正在構建一個可重用的庫,那麼這可能比如果你正在構建一個單一的web應用程序更爲重要。我嘗試做的另一件事是讓我的大多數類型的自動可註冊使用此代碼:

public static void AutoRegister(ContainerBuilder builder, params Assembly[] assemblies) 
{ 
    builder.RegisterAssemblyTypes(assemblies) 
     .Where(t => t.GetCustomAttributes(typeof (RegisterServiceAttribute), false).Any()) 
     .AsSelf() 
     .AsImplementedInterfaces(); 
} 

其中RegisterServiceAttribute是我的根項目屬性:

[AttributeUsage(AttributeTargets.Class)] 
[MeansImplicitUse] 
public class RegisterServiceAttribute : Attribute 
{ 
} 

注:MeansImplicitUse是ReSharper的。

然後我把[RegisterService]放在我想自動註冊的任何類上。我的註冊至少有95%是這樣處理的。剩餘的註冊在AutoRegister()的電話後發生。

+0

謝謝,吉姆,您的回覆。我需要考慮你的推薦與我們想要做的事情的關係。 – musicologyman 2011-04-22 13:49:50

+0

是否有可能在一個應用程序的xml和其他代碼註冊一些srvices? – 2015-08-13 15:25:10

4

我不是100%確定你的例子中預期的行爲是什麼 - 好像你多次註冊同一組件,如果這是你的意圖,請忽略這些建議。

  • 如果您使用XML註冊模塊,則不需要在模塊中註冊組件。
  • 同樣,如果您使用XML註冊模塊,則不需要在代碼中註冊該模塊。

關於「最佳實踐」,我會說Jim的建議是儘量少用XML。就我個人而言,我傾向於完成模塊中的所有繁重工作,然後通過XML註冊模塊以利用可在此處應用的配置。

我想提出的另一個建議是使用XML來配置模塊。在你的例子中,你正在設置一個組件的配置;如果將參數應用於模塊,則配置不易脆弱,然後該模塊的內部將根據需要將它們傳遞給組件。模塊不傾向於流失很多,而組件需要能夠在不中斷配置的情況下進行更改。

HTH,

尼克