【问题标题】:AutoFac not properly resolving by typeAutoFac 无法按类型正确解析
【发布时间】:2014-12-08 03:23:14
【问题描述】:

我一直在尝试了解有关 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));

正如您希望从代码中的 cmets 中看到的那样,当我得到一个 SubCommands 列表然后在列表上执行 Single 时,我得到了一个子命令的实例,但是当我尝试通过直接传入类型,它返回null。是我做错了什么,还是 AutoFac 中存在错误或介于两者之间?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 dependency-injection 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,因此您可以看到这两个选项的实际效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-25
      • 2014-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多