Castle Windsor: не удается разрешить контроллер, если регистрация прошла нормально - PullRequest
0 голосов
/ 15 декабря 2018

У меня есть проект Web Api и я использую Castle Windsor в качестве IoC.Я делал это довольно много раз и, честно говоря, я не могу понять, почему это не работает, поэтому здесь все, что я делаю:

Контроллер в проекте Web Api: Ничего особенного здесь

public class TestController : ApiController, ITestController  
{  
...  //Currently with its default constructor.
}

Global.asax

    public class WebApiApplication : System.Web.HttpApplication
    {
        private readonly IWindsorContainer container;

        public WebApiApplication()
        {
            container = new WindsorContainer().Install(FromAssembly.Named("DependenciesConfiguration"));
        }

        protected void Application_Start()
        {
            GlobalConfiguration.Configure(WebApiConfig.Register);
            GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new DiControllerActivator(container));
        }
}

Класс DiControllerActivation Это класс, который заменяет активатор контроллера по умолчанию в классе Global.asax.

public class DiControllerActivator : IHttpControllerActivator
{
    private readonly IWindsorContainer container;

    public DiControllerActivator(IWindsorContainer container)
    {
        this.container = Argument.NotNull(container, (nameof(container)));
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        //This is the line that fails saying "No component for supporting the service TestController was found.
        var controller = (IHttpController)container.Resolve(controllerType);

        request.RegisterForDispose(new Release(() => container.Release(controller)));

        return controller;
    }
}

internal class Release : IDisposable
{
    private readonly Action release;

    public Release(Action release)
    {
        this.release = release;
    }

    public void Dispose()
    {
        this.release();
    }
}

И, наконец, установщик веб-служб

public class ServicesInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromAssemblyNamed("WebServices")
            .Where(type => type.Name.EndsWith("Controller"))
            .WithService.DefaultInterfaces()
            .Configure(c => c.LifestylePerWebRequest()));
    }
}

Что действительно расстраивает, так это то, что, как я уже сказал, я уже делал это раньше, я пошел на свою предыдущую работу, чтобы посмотреть, что я что-то упустил, и не могу найти что-то, и это всегда работало хорошо.

При запуске приложения после запуска установщика я вижу, что служба находится в контейнере, и когда она перестает работать, говоря: «Не найден компонент для поддержки службы TestController», я все равно вижу службу в контейнерев окне просмотра.

Я использую Castle версии 4.0

Спасибо за любые подсказки и помощь.

1 Ответ

0 голосов
/ 16 декабря 2018

Как оказалось, в этом коде есть тонкое, но критическое отличие от других случаев, когда я делал это ... Тот факт, что TestController реализует интерфейс и регистрируется как таковой, портит все это.

Поскольку метод Create в классе DiActivator пытается разрешить контроллер на основе его типа, а не его интерфейса по умолчанию, контейнер не может его найти.

Одним из решений является просто удалить интерфейс из контроллера илидобавьте необходимый код в метод Create, который получает интерфейс по умолчанию для полученного типа и разрешает его.

...