Настройка инъекции зависимостей с помощью ASP.NET Web API 2.1
Я создаю ASP.NET Web API 2.1 site и поскольку я хочу вводить зависимости непосредственно в контроллеры, я создал свою собственную реализацию IDependencyResolver, чтобы StructureMap обработал это для меня.
public class StructureMapDependencyResolver : IDependencyResolver
{
public IDependencyScope BeginScope()
{
return this;
}
public object GetService(Type serviceType)
{
return ObjectFactory.GetInstance(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return ObjectFactory.GetAllInstances(serviceType).Cast<object>();
}
public void Dispose()
{
}
}
затем я сказал Web API использовать этот класс, добавив эту строку в метод Application_Start в Global.асакс
GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver();
, который компилируется, но когда я попытался получить доступ к любому из методов API в браузере, я получил ошибку, как это
No Default Instance defined for PluginFamily System.Web.Http.Hosting.IHostBufferPolicySelector, System.Web.Http
Это было относительно легко решить, поскольку я добавил строку в свою конфигурацию StructureMap
this.For<IHostBufferPolicySelector>().Use<WebHostBufferPolicySelector>();
однако затем я получил другие подобные ошибки для другой системы.Сеть.Http-классы, и хотя я мог бы решить некоторые из них, я застрял на том, как справиться с 3 из них, а именно ITraceManager, IExceptionHandler и IContentNegotiator.
проблема в том, что TraceManager, который кажется реализацией ITraceManager по умолчанию, является внутренним классом и поэтому я не могу ссылаться на него в своей конфигурации StructureMap.
Итак, я иду об этом совершенно неправильно или есть какой-то другой способ ввести эти внутренние классы?
2 ответов
Я хотел бы дать вам предложение и объяснение, почему бы не пойти этим путем, и как сделать это по-другому (я бы даже сказал, лучше и правильно).
полное и полное объяснение несоответствующего IDependencyResolver
дизайн можно найти здесь: впрыска зависимости и управление продолжительности жизни с ASP.NET Web API Марк Seemann
позвольте мне процитировать эти существенные части:
проблема с IDependencyResolver
главная проблема
IDependencyResolver
что это Локатор Службы. Есть много проблем с Локатор Службы анти-шаблон, но большинство из них я уже описал на этом блоге (и в моей книге). Один из недостатков Service Locator, о котором я еще не написал так много, заключается в том, что в каждом вызове GetService нет контекста вообще. Это общая проблема с локатором служб анти-шаблон, а не только с IDependencyResolver.
а также:
...график зависимостей должен что-то знать о контексте. Что URL-адрес запроса? Что базовый адрес (имя хоста и т. д.) просил? Как вы можете совместно использовать экземпляры зависимостей в одном запросе? Чтобы ответить на такие вопросы, вы должны знать о контексте, а IDependencyResolver не предоставляет эту информацию.
короче,
IDependencyResolver
не права крюк для создания графиков зависимостей. ** К счастью, ASP.NET веб-API имеет лучшую точку расширения для этой цели. **
ServiceActivator
таким образом, ответ в этом сценарии будет ServiceActivator
. Пожалуйста, взгляните на этот ответ:
пример ServiceActivator
:
public class ServiceActivator : IHttpControllerActivator
{
public ServiceActivator(HttpConfiguration configuration) {}
public IHttpController Create(HttpRequestMessage request
, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
var controller = ObjectFactory.GetInstance(controllerType) as IHttpController;
return controller;
}
}
все, что мы можем сделать с StructureMap, на месте. Этот основные возможности Web API framework по-прежнему существуют... мы не должны взламывать их. И мы также скорее используем DI / IoC, чем Service locator
просто попробуйте использовать UnityHierarchicalDependencyResolver вместо другого. У меня получилось. Это для дальнейшего использования, если кто-то хочет использовать Unity