2012-07-04 8 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 ")));' –

関連する問題