ASP Web Api - IoC - Resolve HttpRequestMessage

前端 未结 2 1318
耶瑟儿~
耶瑟儿~ 2020-12-31 12:34

I am trying to set up Castle Windsor with ASP.NET WebAPI.

I am also using the Hyprlinkr package (https://github.com/ploeh/Hyprlinkr) and so need an instance of HttpR

相关标签:
2条回答
  • 2020-12-31 13:06

    Here's a Composition Root that works for me:

    public class WindsorCompositionRoot : IHttpControllerActivator
    {
        private readonly IWindsorContainer container;
    
        public WindsorCompositionRoot(IWindsorContainer container)
        {
            this.container = container;
        }
    
        public IHttpController Create(
            HttpRequestMessage request,
            HttpControllerDescriptor controllerDescriptor,
            Type controllerType)
        {
            var controller = (IHttpController)this.container.Resolve(
                controllerType,
                new
                {
                    request = request
                });
    
            request.RegisterForDispose(
                new Release(
                    () => this.container.Release(controller)));
            return controller;
        }
    
        private class Release : IDisposable
        {
            private readonly Action release;
    
            public Release(Action release)
            {
                this.release = release;
            }
    
            public void Dispose()
            {
                this.release();
            }
        }
    }
    

    Here's how I create the container:

    this.container =
        new WindsorContainer(
            new DefaultKernel(
                new InlineDependenciesPropagatingDependencyResolver(),
                new DefaultProxyFactory()),
            new DefaultComponentInstaller())
            .Install(new MyWindsorInstaller());
    

    and here's the InlineDependenciesPropagatingDependencyResolver:

    public class InlineDependenciesPropagatingDependencyResolver : 
        DefaultDependencyResolver
    {
        protected override CreationContext RebuildContextForParameter(
            CreationContext current,
            Type parameterType)
        {
            if (parameterType.ContainsGenericParameters)
            {
                return current;
            }
    
            return new CreationContext(parameterType, current, true);
        }
    }
    

    Finally, here's how I register RouteLinker:

    container.Register(Component
        .For<RouteLinker, IResourceLinker>()
        .LifestyleTransient());
    

    One thing to be aware of is that the ApiController base class has a public property named Request of the HttpRequestMessage type. As explained in section 10.4.3 of my book Windsor will attempt to assign a value to each writeable property if it has a matching component - and that match is case-insensitive.

    When you pass an HttpRequestMessage named request to the Resolve method, this is exactly what happens, so you need to tell Castle Windsor that it should forego Property Injection for ApiControllers. Here's how I don that in a convention-based registration:

    container.Register(Classes
        .FromThisAssembly()
        .BasedOn<IHttpController>()
        .ConfigureFor<ApiController>(c => c.Properties(pi => false))
        .LifestyleTransient());
    
    0 讨论(0)
  • 2020-12-31 13:12

    Why not to use already built-in mechanism in ASP.NET Web API - Dependency resolver

    http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver

    In project WebApiContrib there is CastleWindsor resolver implementation, but as I've seen with Dependency resolver

    https://github.com/WebApiContrib/WebApiContrib.IoC.CastleWindsor

    And as Mark said in comment - one of the ways to implement IHttpControllerActivator

    http://blog.ploeh.dk/2012/10/03/DependencyInjectionInASPNETWebAPIWithCastleWindsor.aspx

    0 讨论(0)
提交回复
热议问题