Autofac и ASP.NET Web API ApiController - PullRequest
       11

Autofac и ASP.NET Web API ApiController

9 голосов
/ 26 февраля 2012

Я уже некоторое время пользуюсь autofac с MVC 3 и мне это нравится.Недавно я обновил проект до MVC 4, и, похоже, все работает, кроме Web Api ApiControllers.Я получаю следующее исключение:

An error occurred when trying to create a controller of type 'MyNamespace.Foo.CustomApiController'. Make sure that the controller has a parameterless public constructor.

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

Ответы [ 2 ]

10 голосов
/ 09 марта 2012

Я выпустил пакеты интеграции Autofac на NuGet для бета-версий MVC 4 и Web API. Интеграции создадут область действия Autofac для каждого запроса контроллера (контроллер MVC или контроллер API в зависимости от интеграции). Это означает, что контроллер и его зависимости будут автоматически расположены в конце каждого вызова. Оба пакета могут быть установлены параллельно в одном проекте.

MVC 4

https://nuget.org/packages/Autofac.Mvc4

http://alexmg.com/post/2012/03/09/Autofac-ASPNET-MVC-4-(Beta)-Integration.aspx

Веб-API

https://nuget.org/packages/Autofac.WebApi/

http://alexmg.com/post/2012/03/09/Autofac-ASPNET-Web-API-(Beta)-Integration.aspx

Ссылки теперь исправлены.

4 голосов
/ 27 февраля 2012

Я только что настроил это в одном из моих приложений. Есть разные способы сделать это, но мне нравится этот подход:

Интеграция с Autofac и ASP.NET Web API System.Web.Http.Services.IDependencyResolver

Сначала я создал класс, который реализует интерфейс System.Web.Http.Services.IDependencyResolver.

internal class AutofacWebAPIDependencyResolver : System.Web.Http.Services.IDependencyResolver {

    private readonly IContainer _container;

    public AutofacWebAPIDependencyResolver(IContainer container) {

        _container = container;
    }

    public object GetService(Type serviceType) {

        return _container.IsRegistered(serviceType) ? _container.Resolve(serviceType) : null;
    }

    public IEnumerable<object> GetServices(Type serviceType) {

        Type enumerableServiceType = typeof(IEnumerable<>).MakeGenericType(serviceType);
        object instance = _container.Resolve(enumerableServiceType);
        return ((IEnumerable)instance).Cast<object>();
    }
}

И у меня есть еще один класс, в котором хранятся мои регистрации:

internal class AutofacWebAPI {

    public static void Initialize() {
        var builder = new ContainerBuilder();
        GlobalConfiguration.Configuration.ServiceResolver.SetResolver(
            new AutofacWebAPIDependencyResolver(RegisterServices(builder))
        );
    }

    private static IContainer RegisterServices(ContainerBuilder builder) {

        builder.RegisterAssemblyTypes(typeof(MvcApplication).Assembly).PropertiesAutowired();

        builder.RegisterType<WordRepository>().As<IWordRepository>();
        builder.RegisterType<MeaningRepository>().As<IMeaningRepository>();

        return
            builder.Build();
    }
}

Затем инициализируйте его на Application_Start:

protected void Application_Start() {

    //...

    AutofacWebAPI.Initialize();

    //...
}

Надеюсь, это поможет.

...