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

Смежные вопросы