Замок Виндзор / DelegatingHandler / Инъекция IPrincipal Dependency (DI) / Инверсия управления (IoC) в ASP.NET Web API

Я решил почистить этот пост и опубликовал пример проекта наge.tt/3EwoZEd/v/0?c

Уже потратил около 30 часов на это и до сих пор могуне понимаю ... помощь будет очень признателен!

У меня есть решение ASP.NET Web API, которое использует этот код:http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/ реализовать "Базовая HTTP-аутентификация в ASP.NET Web API с использованием обработчиков сообщений ", Я'я новичок в IoC / DI и япытаюсь заставить это работать с замком Виндзор.

Я пробовал много разных вещей, но я получаю 1 из следующих ошибок в зависимости от того, что я сделал неправильно: "

Похоже, вы забыли зарегистрировать http модуль Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule ""В экземпляре объекта не задана ссылка на объект." для основного провайдера в BasicAuthMessageHandler "Компонент для поддержки сервиса * .DummyPrincipalProvider не найден "

Ниже мой код:

Global.asax.cs:

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);

    var config = (CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors");

    IncludeErrorDetailPolicy errorDetailPolicy;

    switch (config.Mode)
    {
        case CustomErrorsMode.RemoteOnly:
            errorDetailPolicy
                = IncludeErrorDetailPolicy.LocalOnly;
            break;
        case CustomErrorsMode.On:
            errorDetailPolicy
                = IncludeErrorDetailPolicy.Never;
            break;
        case CustomErrorsMode.Off:
            errorDetailPolicy
                = IncludeErrorDetailPolicy.Always;
            break;
        default:
            throw new ArgumentOutOfRangeException();
    }

    GlobalConfiguration.Configuration.IncludeErrorDetailPolicy = errorDetailPolicy;

    ConfigureWindsor(GlobalConfiguration.Configuration);

    GlobalConfiguration.Configuration.MessageHandlers.Add(new BasicAuthMessageHandler()
    {
        PrincipalProvider = _container.Resolve()
    });
}

public static void ConfigureWindsor(HttpConfiguration configuration)
{
    // Create / Initialize the container  
    _container = new WindsorContainer();

    // Find our IWindsorInstallers from this Assembly and optionally from our DI assembly which is in abother project.  
    _container.Install(FromAssembly.This());
    _container.Kernel.Resolver.AddSubResolver(new CollectionResolver(_container.Kernel, true));

    //Documentation http://docs.castleproject.org/Windsor.Typed-Factory-Facility.ashx  
    // Set the WebAPI DependencyResolver to our new WindsorDependencyResolver  
    var dependencyResolver = new WindsorDependencyResolver(_container);
    configuration.DependencyResolver = dependencyResolver;
}

Виндзорский установщик:

public class PrincipalsInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(Classes.FromThisAssembly().BasedOn());

        container.Register(
            Component.For().ImplementedBy()
        );
    }
}

Модифицированный DummyPrincipalProvider (из оригинала, который я получил отURL выше):

public class DummyPrincipalProvider : IProvidePrincipal
{
    private IUserRepository _userRepo;

    public DummyPrincipalProvider(IUserRepository userRepo)
    {
        this._userRepo = userRepo;
    }

    public IPrincipal CreatePrincipal(string username, string password)
    {
        try
        {
            if (!this._userRepo.ValidateUser(username, password))
            {
                return null;
            }
            else
            {
                var identity = new GenericIdentity(username);
                IPrincipal principal = new GenericPrincipal(identity, new[] { "User" });

                if (!identity.IsAuthenticated)
                {
                    throw new ApplicationException("Unauthorized");
                }

                return principal;
            }
        }
        catch
        {
            return null;
        }
    }
}

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 GetServices(Type t)
    {
        return _container.ResolveAll(t).Cast().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 GetServices(Type t)
    {
        return _container.ResolveAll(t).Cast().ToArray();
    }

    public void Dispose()
    {
        _scope.Dispose();
    }
}

Ответы на вопрос(1)

Ваш ответ на вопрос