Ответ 1
CodeCaster, Noctis и Cristiano благодарим вас за вашу помощь и руководство. Я только что получил решение для моего запроса -
Первым шагом является использование nuget для установки пакетов Windsor.Castle в WebApi.
Рассмотрим следующий фрагмент кода -
Интерфейс IWatch.cs
public interface IWatch
{
DateTime GetTime();
}
Класс Watch.cs
public class Watch:IWatch
{
public DateTime GetTime()
{
return DateTime.Now;
}
}
ApiController WatchController.cs определяется следующим образом: -
public class WatchController : ApiController
{
private readonly IWatch _watch;
public WatchController(IWatch watch)
{
_watch = watch;
}
public string Get()
{
var message = string.Format("The current time on the server is: {0}", _watch.GetTime());
return message;
}
}
В контроллере мы ввели зависимость через объект IWatch в конструкторе WatchController. Я использовал IDependencyResolver и IDependencyScope для достижения инъекции зависимостей в web api. Интерфейс IDependencyResolver используется для разрешения всего за пределами области запроса.
WindsorDependencyResolver.cs
internal sealed class WindsorDependencyResolver : IDependencyResolver
{
private readonly IWindsorContainer _container;
public WindsorDependencyResolver(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public IDependencyScope BeginScope()
{
return new WindsorDependencyScope(_container);
}
public void Dispose()
{
}
}
WindsorDependencyScope.cs
internal sealed class WindsorDependencyScope : IDependencyScope
{
private readonly IWindsorContainer _container;
private readonly IDisposable _scope;
public WindsorDependencyScope(IWindsorContainer container)
{
if (container == null)
{
throw new ArgumentNullException("container");
}
_container = container;
_scope = container.BeginScope();
}
public object GetService(Type t)
{
return _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
}
public IEnumerable<object> GetServices(Type t)
{
return _container.ResolveAll(t).Cast<object>().ToArray();
}
public void Dispose()
{
_scope.Dispose();
}
}
WatchInstaller.cs
Установщики - это просто типы, которые реализуют интерфейс IWindsorInstaller. Интерфейс имеет один метод, называемый Install. Метод получает экземпляр контейнера, который затем может регистрировать компоненты с использованием свободного API регистрации:
public class WatchInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
//Необходимо зарегистрировать контроллеры явно в вашем контейнере // В противном случае получится Исключение:
Произошла ошибка при попытке создать//контроллер типа 'XxxxController. Убедитесь, что контроллер имеет без параметров публичный конструктор.
//Причина: В основном, произошло то, что вы не зарегистрировали свои контроллеры явно в своем контейнере. Windsor пытается разрешить вам незарегистрированные конкретные типы, но поскольку он не может его решить (вызванный ошибкой в вашей конфигурации), он возвращает null. Он вынужден вернуть null, потому что Web API заставляет его делать это из-за контракта IDependencyResolver. Поскольку Windsor возвращает значение null, Web API попытается создать сам контроллер, но поскольку он не имеет конструктора по умолчанию, он выдает исключение "Убедитесь, что контроллер имеет исключение без параметров". Это сообщение об ошибке вводит в заблуждение и не объясняет истинную причину.
***container.Register(Classes.FromThisAssembly()
.BasedOn<IHttpController>()
.LifestylePerWebRequest());***
container.Register(
Component.For<IWatch>().ImplementedBy<Watch>()
);
}
}
Наконец, нам нужно заменить преобразователь зависимостей по умолчанию с реализацией Windsor в Global.asax.cs(метод Application_Start) и установить наши зависимости:
private static IWindsorContainer _container;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureWindsor(GlobalConfiguration.Configuration);
}
public static void ConfigureWindsor(HttpConfiguration configuration)
{
_container = new WindsorContainer();
_container.Install(FromAssembly.This());
_container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));
var dependencyResolver = new WindsorDependencyResolver(_container);
configuration.DependencyResolver = dependencyResolver;
}