2012-07-04 29 views
6

我似乎在做這在我的代碼公平一點:我必須使用Autofac顯式綁定普通類嗎?

public class ActionsModule : Module 
    { 
     protected override void Load(ContainerBuilder builder) 
     { 
      base.Load(builder); 
      builder.Register(c => LogManager.GetCurrentClassLogger()).As<ILog>().InstancePerDependency(); 

      // Autofac doesn't seem to be able to inject things without explicit binding 
      builder.RegisterType<ComboActions>().As<ComboActions>().InstancePerHttpRequest(); 
      builder.RegisterType<AppActions>().As<AppActions>().InstancePerHttpRequest(); 
     } 
    } 
} 

凡「動作」類我需要一個類被注入到我的控制器,並具有各種其他子依賴性。

似乎有點垃圾。爲什麼autofac無法解決這個類有一個已經滿足的依賴的構造函數,並自動生成一個實例?

我的意思是,如果A類需要注入B類,而B類需要C,D,E等足夠公平,那麼我猜你不想走遍整個依賴鏈,看看你是否可以創建一個類在運行時。 ...但是如果A類直接依賴於明確約束的C和D,肯定這是一個微不足道的情況?

我錯過了什麼嗎?似乎看不到任何這方面的文件... ...

回答

2

AFAIK,Autofac要求每個需要的類型在容器中註冊,但這並不意味着你必須單獨做每一個。我註冊的近99%通過增加該屬性的類型進行處理:

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

因此,例如,你必須

[AutoRegister] 
class ComboActions 
{ 

然後我這個註冊它們:

public class AutoScanModule : Module 
{ 
    private readonly Assembly[] _assembliesToScan; 

    public AutoScanModule(params Assembly[] assembliesToScan) 
    { 
     _assembliesToScan = assembliesToScan; 
    } 

    protected override void Load(ContainerBuilder builder) 
    { 
     builder.RegisterAssemblyTypes(_assembliesToScan) 
      .Where(t => t.GetCustomAttributes(typeof (AutoRegisterAttribute), false).Any()) 
      .AsSelf() 
      .AsImplementedInterfaces() 
      .InstancePerLifetimeScope(); 
    } 
} 

就像我說的,這涵蓋了我的大部分註冊,然後我通常只需要擔心第三方類型,開放泛型和裝飾器等事情。

編輯:檢查出reply from Kaleb,證明我錯了。很酷的功能,我從來不知道!

20

您不必註冊所有類型。 Autofac提供了一個AnyConcreteTypeNotAlreadyRegisteredSource,如果您尚未提供註冊,它將自動獲取具體類型。

例如:

var builder = new ContainerBuilder(); 
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); 
var container = builder.Build(); 
... 
var myConcreteType = container.Resolve<MyConcreteType>(); 

的源允許更復雜的事情,比如automatically injecting mocked objects爲接口和抽象基於類的依賴關係。

+0

哇。從來不知道這一點。 TIL! –

+1

這是驚人的,特別是因爲你可以做一些像'builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource(x => x.Name.Contains(「ViewModel」)));'' –

相關問題