2014-12-07 85 views
1

我一直在嘗試瞭解有關AutoFac的更多信息,並遇到了對我來說沒有任何意義的情況。我創建了一個示例應用程序來突出顯示我的問題,以便原諒這個奇怪的示例。基本上,我試圖按類型來解析接口,示例應用程序有一個命令,它接受一種類型的子命令來運行,然後嘗試解析子命令。我能用一種技術解決子命令,但不能解決其他問題。AutoFac未按照類型正確解析

這裏是我的應用程序和控制器代碼

public interface ISubCommand 
{ 
    void Run(); 
} 

public class OneSubCommand : ISubCommand 
{ 
    public void Run() 
    { 
     //fake do something 
    } 
} 

public class TwoSubCommand : ISubCommand 
{ 
    public void Run() 
    { 
     //fake do something 
    } 
} 


public class TestCommand 
{ 

    private readonly Type _type; 

    public TestCommand(Type type) 
    { 
     _type = type; 
    } 

    public void Run() 
    { 

     //this works and subcommandLive gets to be an instance of OneSubCommand 
     var subcommands = DependencyResolver.Current.GetService<IEnumerable<ISubCommand>>(); 
     var subcommandLive = subcommands.Single(x => x.GetType().FullName == _type.FullName); 

     //this does not work and subcommandNULL is NULL 
     var subcommandNULL = DependencyResolver.Current.GetService(_type); 

     //do something 

    } 

} 

public class HomeController : Controller 
{ 

    public ActionResult Index() 
    { 


     var command = new TestCommand(typeof(OneSubCommand)); 
     command.Run(); 

     return View(); 
    } 

} 

這裏是我的Global.asax.cs

//setup the container 
var builder = new ContainerBuilder(); 

//make sure all sub commands get registered 
builder.RegisterType<OneSubCommand>().As<ISubCommand>(); 
builder.RegisterType<TwoSubCommand>().As<ISubCommand>(); 

//build the container and set it as the default 
var container = builder.Build(); 
DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 

容器代碼你可以從我的意見在代碼中希望看到的,當我得到一個SubCommands列表,然後在列表上做一個Single時,我得到了一個子命令的實例,但是當我嘗試通過直接傳入類型來獲取實例時,它將返回null。我做錯了什麼,或者AutoFac中存在一個錯誤?

回答

1

Autofac要求每種類型在解析類型之前進行明確註冊,它不支持自動佈線以用於開箱即用的具體類型。

可以手動註冊的每個命令ISubCommand和作爲登記類型時使用AsSelf()其具體類型:

builder.RegisterType<OneSubCommand>() 
     .AsSelf() 
     .As<ISubCommand>(); 
builder.RegisterType<TwoSubCommand>() 
     .AsSelf() 
     .As<ISubCommand>(); 

有使用AnyConcreteTypeNotAlreadyRegisteredSource特徵的另一種選擇,這將允許容器以解決任何具體類型而不不必明確電線它:

builder.RegisterType<OneSubCommand>() 
     .As<ISubCommand>(); 
builder.RegisterType<TwoSubCommand>() 
     .As<ISubCommand>();  
builder.RegisterSource(
     new Autofac.Features.ResolveAnything.AnyConcreteTypeNotAlreadyRegisteredSource()); 

我創建this fiddle所以你可以看到在行動這兩個選項。

+0

非常感謝!學到了新東西。 – zgirod 2014-12-08 01:59:19