Не удается заставить Autofac работать с Web API 2 - PullRequest
0 голосов
/ 31 января 2019

Я изо всех сил пытаюсь заставить Autofac работать с контроллерами WebApi2

Я всегда получаю сообщение об ошибке, что нет конструктора без параметров

{
    "Message": "An error has occurred.",
    "ExceptionMessage": "An error occurred when trying to create a controller of type 'GatewayController'. Make sure that the controller has a parameterless public constructor.",
    "ExceptionType": "System.InvalidOperationException",
    "StackTrace": "   at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   at System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()",
    "InnerException": {
        "Message": "An error has occurred.",
        "ExceptionMessage": "Type 'Gv8ApiGateway.Controllers.GatewayController' does not have a default constructor".....
    }
}

Я просматривал множество постов в этом онлайни я не вижу, что я что-то пропустил

Когда я смотрю на свой контейнер после его сборки, я вижу, что он содержит мой контроллер

Я использую TopShelf

    HostFactory.Run(x => //1
    {
        x.UseAutofacContainer(container);

        x.Service<IMyService>(s => //2
        {
            s.ConstructUsingAutofacContainer();
            s.WhenStarted(tc => tc.Start());
            s.WhenStopped(tc => tc.Stop());
        });
        x.SetStartTimeout(TimeSpan.FromMinutes(4));
        x.StartAutomatically();
        x.RunAsLocalSystem();
        x.EnableServiceRecovery(r => { r.RestartService(0); });
        x.SetDescription($"DESCRIPTION");
        x.SetDisplayName($"DISPLAY NAME");
        x.SetServiceName($"NAME");
    });

В моем модуле сборки у меня есть проверенная строка, которая называется

builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

В моем классе, который запускается TopShelf, у меня есть -

var resolver = new AutofacWebApiDependencyResolver(_container);
GlobalConfiguration.Configuration.DependencyResolver = resolver;
_webApi = WebApp.Start<Startup>("http://localhost:8084");

Мой запусккласс -

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        // Configure Web API for self-host. 
        var config = new HttpConfiguration();

        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new {id = RouteParameter.Optional}
        );

        app.UseWebApi(config);


    }
}

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

Мой контроллер:

public class GatewayController : ApiController
{
    private readonly IMyService_myService;

    public GatewayController(IMyService myService)
    {
        Argument.IsNotNull(() => myService);

        _myService = myService;
    }


}

Кто-нибудь может увидеть, что я сделал неправильно, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Ваш класс запуска Web API показывает, что вы используете конвейер OWIN.Мы видим это потому, что вы создаете HttpConfiguration с нуля.

app.UseWebApi(config);

Если вы ознакомились с документацией по интеграции Web API OWIN , вы можете увидетьпример того, как это меняется. Ключ в том, что вы должны установить config.DependencyResolver, а не GlobalConfiguration.DependencyResolver.

Как отмечено в документации:

Распространенная ошибка в интеграции OWINэто использование GlobalConfiguration.Configuration. В OWIN вы создаете конфигурацию с нуля. Вы не должны ссылаться на GlobalConfiguration.Configuration нигде при использовании интеграции OWIN.

Имейте в виду, что есть пара дополнительных шагов, чтобы убедиться, чтоOWIN конвейер будет работать правильно с Autofac. Есть документы по настройке базового конвейера OWIN и есть дополнительное специальное промежуточное ПО для веб-API Autofac, которое необходимо добавить

Я не вижу ни одного из Autofacпромежуточное программное обеспечение при запуске веб-API, что также может вызвать проблемы.Я бы рекомендовал вернуться и посмотреть на некоторые из этих документов.

0 голосов
/ 31 января 2019

Вы должны зарегистрировать свой сервис и интерфейс в контейнере, как показано ниже.

container.Register<IMyService, MyService>();

Перед настройкой конфигурации TopSelf добавьте приведенный выше код.Это будет работать.

...