我一直在努力了解有关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时,我得到一个子命令的实例但是当我尝试通过直接传入一个实例来获取一个实例时type,返回null。我做错了什么,或者AutoFac中是否有错误或介于两者之间?
答案 0 :(得分: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,因此您可以看到两个选项。