Note that there are some explanatory texts on larger screens.

plurals
  1. POCastle Windsor/DelegatingHandler/IPrincipal Dependency Injection (DI)/Inversion of Control (IoC) in ASP.NET Web API
    primarykey
    data
    text
    <p>I decided to clean this post up and I posted a sample project at <a href="http://ge.tt/3EwoZEd/v/0?c" rel="nofollow">ge.tt/3EwoZEd/v/0?c</a></p> <p>Spent around 30 hours on this already and still can't figure it out... help would be really appreciated!</p> <p>I have an ASP.NET Web API solution that uses this code: <strong><a href="http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/" rel="nofollow">http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/</a></strong> to implement "Basic HTTP authentication in ASP.NET Web API using Message Handlers". I'm new to IoC/DI and I'm trying to get this to work with Castle Windsor.</p> <p>I've been trying a lot of different things but I get 1 of the following errors depending on what I did wrong:</p> <ul> <li>"Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule"</li> <li>"Object reference not set to an instance of an object." for the PrincipalProvider in BasicAuthMessageHandler</li> <li>"No component for supporting the service *.DummyPrincipalProvider was found"</li> </ul> <p>Below is my code:</p> <hr> <p><strong>Global.asax.cs:</strong></p> <pre><code>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&lt;IProvidePrincipal&gt;() }); } 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; } </code></pre> <hr> <p><strong>Windsor Installer:</strong></p> <pre><code>public class PrincipalsInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Classes.FromThisAssembly().BasedOn&lt;DelegatingHandler&gt;()); container.Register( Component.For&lt;IProvidePrincipal&gt;().ImplementedBy&lt;DummyPrincipalProvider&gt;() ); } } </code></pre> <hr> <p><strong>Modified DummyPrincipalProvider (from the original I got from the <a href="http://www.piotrwalat.net/basic-http-authentication-in-asp-net-web-api-using-message-handlers/" rel="nofollow">URL above</a>):</strong></p> <pre><code>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; } } } </code></pre> <hr> <p><strong>WindsorDependencyResolver.cs:</strong></p> <pre><code>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&lt;object&gt; GetServices(Type t) { return _container.ResolveAll(t).Cast&lt;object&gt;().ToArray(); } public IDependencyScope BeginScope() { return new WindsorDependencyScope(_container); } public void Dispose() { } } </code></pre> <hr> <p><strong>WindsorDependencyScope.cs:</strong></p> <pre><code>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&lt;object&gt; GetServices(Type t) { return _container.ResolveAll(t).Cast&lt;object&gt;().ToArray(); } public void Dispose() { _scope.Dispose(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload