Настройка инъекции зависимостей с помощью 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