I keep getting an errors trying to implement IHttpControllerActivator
Most recent is on this line --
container.Register(Component.For<IHttpControllerActivator>().ImplementedBy<ContextCapturingControllerActivator>());
Error - "Method 'Create' in type
'My.Utilities.CastleWindsor.ContextCapturingControllerActivator' from
assembly 'My.Utilities, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null' does not have an implementation...




How can I make the Windsor container register my ApiControllers and
all of the Interfaces/Classes (internal & abstract) from the dlls so
all of the solutions work together?




I have three separate solutions each containing a project(s).  It is a
requirement that these solutions remain separate and distinct and not
be grouped together under one main solution.
These solutions are supposed to use IoC/Dependency Injection so they
are loosly coupled.




1. First solution -  My.Utilities is a class library which contains
various classes/interfaces that are used by multiple projects (castle
windsor, db connections/commands/etc., logging, email, etc.)
2. Second solution - My.Schedule is also a class library that contains
the CRUD for getting a schedule and any business logic that needs to
be done. This project references My.Utilities.
There will eventually be several more solutions like #2 and all will
be referenced by the WebAPI.  Each solution will do CRUD on specific
data. All of these will also reference My.Utilities.
3. Third solution - My.Web.Mvc, this uses the two class library dlls
(My.Utilities/MySchedule) as references. This is built with MVC4
WebAPI and uses the latest release of the MVC4 code.




Eventually there will be a part 4 to this project that will probably
need to use Windsor - the phone apps (Mono and JQuery Mobile).




Below is part of the code but should give you an idea of what is going
on:
-----------------------------------------------------------------------------------------------
My.Utilities Solution (Class Library)




using System;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;




namespace My.Utilities.CastleWindsor
{
    public class ContextCapturingControllerActivator :
IHttpControllerActivator
    {
        private readonly IHttpControllerActivator _activator;
        private readonly
Func<TaskCompletionSource<HttpControllerContext>> _promiseFactory;




        public
ContextCapturingControllerActivator(Func<TaskCompletionSource<HttpControllerContext>>
promiseFactory, IHttpControllerActivator activator)
        {
            this._activator = activator;
            this._promiseFactory = promiseFactory;
        }




        public IHttpController Create(HttpControllerContext
controllerContext, Type controllerType)
        {
            this._promiseFactory().SetResult(controllerContext);
            return this._activator.Create(controllerContext,
controllerType);
        }
    }








}








using System.Collections;
using System.Linq;
using Castle.Core.Internal;
using Castle.MicroKernel.Registration;
using Castle.Windsor;




namespace My.Utilities.CastleWindsor
{
    public class Windsor
    {

        public static IWindsorContainer Container { get { return
(Registry.Instance); } }








        public static T Resolve<T>()
        {
            return (Container.Resolve<T>());
        }








        public static T Resolve<T>(object argumentsAsAnonymousType)
        {
            return (Container.Resolve<T>(argumentsAsAnonymousType));
        }




        public static T Resolve<T>(IDictionary arguments)
        {
            return (Container.Resolve<T>(arguments));
        }








        public static void Release(object component)
        {
            Container.Kernel.ReleaseComponent(component);
        }




        public static T Assemble<T>(T instance) where T : class
        {
            if (instance != null)
            {
                // Look for any properties that can be set
                instance.GetType().GetProperties()
                        .Where(property => property.CanWrite &&
property.PropertyType.IsPublic)
                        .Where(property =>
Container.Kernel.HasComponent(property.PropertyType))
                        .ForEach(property =>
property.SetValue(instance, Container.Resolve(property.PropertyType),
null));
            }
            return (instance);
        }




        /// <summary>
        /// Threadsafe singleton
        /// </summary>
        private class Registry
        {
            /// <summary>Singleton access to container.</summary>
            internal static readonly IWindsorContainer Instance = new
WindsorContainer();




            static Registry()
            {
                //Instance.AddFacility<FactorySupportFacility>();
               // Instance.AddFacility<LoggingFacility>(f =>
f.LogUsing(LoggerImplementation.Log4net).WithConfig("log4Net.config"));




               
Instance.Register(Component.For<IWindsorContainer>().Instance(Instance));
            }
        }




    }
}




using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Castle.MicroKernel;




namespace My.Utilities.CastleWindsor
{

    public class WindsorControllerFactory : DefaultControllerFactory
    {

        private readonly IKernel _kernel;




        public WindsorControllerFactory(IKernel kernel)
        {
            this._kernel = kernel;
        }




        public override void ReleaseController(IController controller)
        {
            _kernel.ReleaseComponent(controller);
        }




        protected override IController
GetControllerInstance(RequestContext requestContext, Type
controllerType)
        {
            if (controllerType == null)
            {
                throw new HttpException(404, string.Format("The
controller for path '{0}' could not be found.",
requestContext.HttpContext.Request.Path));
            }




            return (IController)_kernel.Resolve(controllerType);
        }
    }
}








namespace My.Utilities.Db
{
    /// <summary>
    /// A generic interface that abstracts the details of Oracle data
access structure from the client code.
    /// </summary>
    public interface IDbAccess
    {
        IDbConnection CreateConnection(string connStr);
    }
}




namespace My.Utilities.Db
{
    public abstract class DbAccess : IDbAccess
    {
        public IDbConnection CreateConnection(string connStr)
        {
           ...
        }
    }
}
-----------------------------------------------------------------------------------------------




My.Web.Mvc Solution (MVC4 WebAPI)




using System.Linq;
using System.Net.Http.Formatting;
using System.Reflection;
using System.Runtime.Serialization.Formatters;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Castle.Windsor;
using My.Utilities.CastleWindsor;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Web.Mvc
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode,
    // visit http://go.microsoft.com/?LinkId=9394801




    public class WebApiApplication : System.Web.HttpApplication
    {
        public static void
RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }




        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.IgnoreRoute("{*favicon}", new { favicon = @"(.*/)?
favicon.ico(/.*)?" });
            routes.IgnoreRoute("{*scripts}", new { scripts = @"(.*/)?
scripts/(.*)?" });




            routes.MapHttpRoute(
                name: "schedule-brief",
                routeTemplate: "api/schedule/{ID}/{date}/brief",
                defaults: new
                {
                    controller = "Schedule",
                    action = "GetGeneric"
                },
                constraints: new
                {
                }
            );




            routes.MapHttpRoute(
              name: "schedule",
              routeTemplate: "api/schedule/{ID}/{date}",
              defaults: new
              {
                  controller = "Schedule",
                  action = "Get"
              },
              constraints: new
              {
              }
            );








        /// <summary>
        /// Registers any dependencies for service resolution.
        /// </summary>
        public void RegisterDependencies(IWindsorContainer container,
HttpConfiguration configuration)
        {
           
configuration.ServiceResolver.SetService(typeof(IControllerFactory),
new WindsorControllerFactory(container.Kernel));
            ControllerBuilder.Current.SetControllerFactory(new
WindsorControllerFactory(container.Kernel));
        }








        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();




            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);








           // Dependency Injection / Service Resolver
           IWindsorContainer container = Windsor.Container;
           Registry.Register(container);
           RegisterDependencies(container,
GlobalConfiguration.Configuration);








            BundleTable.Bundles.RegisterTemplateBundles();
        }




        protected void Application_End()
{ Windsor.Container.Dispose(); }
    }
}




using System;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using My.Schedule;
using My.Utilities.CastleWindsor;








namespace Web.Mvc
{
    public class Registry
    {
        public static void Register(IWindsorContainer container)
        {
            //My.Schedule
           
container.Register(Component.For<ISchedule>().ImplementedBy(typeof
(Schedule)));




            //My.Utilities
          
 container.Register(Component.For<IDbAccess>().ImplementedBy(typeof
(DbAccess)));

           
container.Register(Component.For<IHttpControllerActivator>().ImplementedBy<ContextCapturingControllerActivator>());
           
container.Register(Component.For<IHttpControllerActivator>().ImplementedBy<DefaultHttpControllerActivator>());
           
container.Register(Component.For<Func<TaskCompletionSource<HttpControllerContext>>>().AsFactory());
           
container.Register(Component.For<TaskCompletionSource<HttpControllerContext>>().LifestylePerWebRequest());
           
container.Register(Component.For<HttpControllerContext>().UsingFactoryMethod(k
=>k.Resolve<TaskCompletionSource<HttpControllerContext>>().Task.Result).LifestylePerWebRequest());
        }
    }
}












using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using My.Schedule;
using My.Schedule.Models;




namespace Web.Mvc.Controllers
{
    public class ScheduleController : ApiController
    {
        private readonly ISchedule _service;




        public ScheduleController(ISchedule service)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }




            _service = service;
        }




        public IQueryable GetGeneric(int ID, int date)
        {
          IList<Sched> schedule = Get(ID, date).ToList();
            return (schedule.Select(c => new
            {
               ...//Json formatting
            }).AsQueryable());
        }




       public IQueryable<Sched> Get(int ID, int date)
       {




            return _service.GetSchedule(ID, date).AsQueryable();
       }




    }
}




-----------------------------------------------------------------




My.Schedule Solution (Class Library)




using System.Linq;
using System.Text;
using My.Schedule.Models;
using My.Utilities.Db;
using My.Utilities.Logging;








namespace My.Schedule
{
    public interface ISchedule
    {
        IQueryable<Sched> GetSchedule(int ID, int date);
    }
}








using System.Collections.Generic;
using System.Linq;
using My.Schedule.Models;
using My.Schedule.Repository;
namespace My.Schedule
{
 public class Schedule : ISchedule
    {
       private readonly IScheduleRepository _repository;




        public Schedule()
        {
            _repository = new ScheduleRepository();
        }




       public IQueryable<Sched> GetSchedule(int ID, int date)
        {
            ... //business logic
            return (schedule.AsQueryable());
       }
  }
}








using System.Linq;
using MySchedule.Models;




namespace My.Schedule.Repository
{
    internal interface IScheduleDbRepository
    {
        IQueryable<Sched> GetSchedule(int ID, int date);
    }
}












using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OracleClient;
using System.Globalization;
using System.Linq;
using System.Configuration;
using System.Text;
using My.Schedule.Models;
using My.Utilties.Db;




namespace My.Schedule.Repository
{
   internal class ScheduleDbRepository : IScheduleDbRepository
    {




       public IQueryable<Sched> GetSchedule(int ID, int date)
        {
          IList<Sched> schedule = new List<Sched>();




          ...//connect to database, run sql




           return (schedule.AsQueryable());
        }
    }
}

On Apr 30, 1:43 am, John Simons <[email protected]> wrote:
> This post may be able to help 
> you:http://blog.ploeh.dk/2012/04/19/WiringHttpControllerContextWithCastle...
>
>
>
>
>
>
>
> On Monday, April 30, 2012 4:15:36 PM UTC+10, [email protected] wrote:
>
> > Hi,
>
> > I'm new to using Windsor.  I have a new MVC 4 WebAPI project and I'm
> > using the latest code from GitHub.  I need to register my
> > ApiControllers which are based on IHttpController.  However, the
> > IHttpControllerFactory has been deleted from System.Web.Http/
> > Dispatcher. [http://aspnetwebstack.codeplex.com/SourceControl/network/
> > forks/asbjornu/aspnet/changeset/changes/f6a7f35302ba<http://aspnetwebstack.codeplex.com/SourceControl/network/forks/asbjor...>]
>
> > How do I go about registering ApiControllers without
> > IHttpControllerFactory?

-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-users?hl=en.

Reply via email to