Я новичок в Inversion of Control & Autofac. Изучая документацию, я понял, что существует множество концепций ASP.NET Web Api, которые я не совсем понимаю или не имею опыта, что затрудняет определение того, чего не хватает в моей реализации.
Я хочу применить Autofacв существующий проект ASP.NET Web Api, который имеет несколько ApiControllers. Все эти контроллеры имеют общий родительский абстрактный класс. Этот абстрактный класс имеет метод, который отвечает за возврат экземпляра службы. Я надеялся заменить этот метод на внедрение зависимостей Autofac.
Родительский абстрактный класс, от которого наследуется каждый ApiController, очень прост.
public abstract class BaseApiController
{
public IMyService serviceClient { get; set; }
public BaseApiController() {}
public BaseApiController(IMyService serviceClient)
{
this.serviceClient = serviceClient;
}
}
Каждый контроллер наследует от вышеуказанного класса, в то время как некоторыеиспользует метод Get по умолчанию, большинство из них имеют несколько маршрутов. Ни один контроллер не указывает конструктор:
public class MyController : BaseApiController
{
public MyController() : base() {}
public MyController(IMyService serviceClient) : base(serviceClient) {}
[HttpGet]
[Route("api/foo/bar")]
[ActionName("FooBar")]
public string FooBar()
{
using (serviceClient)
{
return serviceClient.GetFooBar() as string;
}
}
}
Autofac интегрирован в метод Application_Start приложений Glabal.asax.cs, регистрируя ServerClientProvider, который должен быть поставщиком, к которому следует обращаться при зависимостик IMyService встречается:
public class Global : System.Web.HttpApplication, IContainerProviderAccessor
{
#region AutoFac
private static IContainerProvider _containerProvider;
public IContainerProvider ContainerProvider => _containerProvider;
#endregion AutoFac
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register(x => ServiceClientProvider.GetServiceClient())
.As<IMyService>()
.InstancePerRequest();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired();
builder.RegisterHubs(Assembly.GetExecutingAssembly()).PropertiesAutowired();
var container = builder.Build();
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
GlobalHost.DependencyResolver = new AutofacDependencyResolver(container);
_containerProvider = new ContainerProvider(container);
}
}
Я настроил приложение ASP.NET, в файле web.config:
<configuration>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="ContainerDisposal" type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web" preCondition="managedHandler" />
<add name="PropertyInjection" type="Autofac.Integration.Web.Forms.PropertyInjectionModule, Autofac.Integration.Web" preCondition="managedHandler" />
</modules>
</system.webServer>
<configuration>
Насколько я понимаю, Autofac должен автоматически разрешить поставщикапри обнаружении контроллера с открытым свойством, которое соответствует зарегистрированному типу (Property Injection), или если существует конструктор с параметром, который соответствует любой зарегистрированной зависимости.
Однако я не получаю никаких ошибок, связанных с моимКонфигурация Autofac. Я получаю исключение NullReferenceException, когда MyController
пытается вызвать метод IMyService.FooBar
.
Чего мне не хватает?
Любая помощь будет принята с благодарностью.