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.