2014-12-07 79 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